CycleGAN, Image-to-Image Translation

In this notebook, we're going to define and train a CycleGAN to read in an image from a set $X$ and transform it so that it looks as if it belongs in set $Y$. Specifically, we'll look at a set of images of Yosemite national park taken either during the summer of winter. The seasons are our two domains!

The objective will be to train generators that learn to transform an image from domain $X$ into an image that looks like it came from domain $Y$ (and vice versa).

Some examples of image data in both sets are pictured below.

Unpaired Training Data

These images do not come with labels, but CycleGANs give us a way to learn the mapping between one image domain and another using an unsupervised approach. A CycleGAN is designed for image-to-image translation and it learns from unpaired training data. This means that in order to train a generator to translate images from domain $X$ to domain $Y$, we do not have to have exact correspondences between individual images in those domains. For example, in the paper that introduced CycleGANs, the authors are able to translate between images of horses and zebras, even though there are no images of a zebra in exactly the same position as a horse or with exactly the same background, etc. Thus, CycleGANs enable learning a mapping from one domain $X$ to another domain $Y$ without having to find perfectly-matched, training pairs!

CycleGAN and Notebook Structure

A CycleGAN is made of two types of networks: discriminators, and generators. In this example, the discriminators are responsible for classifying images as real or fake (for both $X$ and $Y$ kinds of images). The generators are responsible for generating convincing, fake images for both kinds of images.

This notebook will detail the steps one should take to define and train such a CycleGAN.

  1. Load in the image data using PyTorch's DataLoader class to efficiently read in images from a specified directory.
  2. Then, define the CycleGAN architecture according to provided specifications, the discriminator and the generator models.
  3. Complete the training cycle by calculating the adversarial and cycle consistency losses for the generator and discriminator network and completing a number of training epochs.
  4. Finally, evaluate your model by looking at the loss over time and looking at sample, generated images.

Load and Visualize the Data

We'll first load in and visualize the training data, importing the necessary libraries to do so.

In [1]:
!unzip summer2winter_yosemite.zip # can comment out after executing once
Archive:  summer2winter_yosemite.zip
replace summer2winter_yosemite/.DS_Store? [y]es, [n]o, [A]ll, [N]one, [r]ename: ^C
In [1]:
# loading in and transforming data
import os
import torch
from torch.utils.data import DataLoader
import torchvision
import torchvision.datasets as datasets
import torchvision.transforms as transforms

# visualizing data
import matplotlib.pyplot as plt
import numpy as np
import warnings

%matplotlib inline

DataLoaders

The get_data_loader function returns training and test DataLoaders that can load data efficiently and in specified batches. The function has the following parameters:

  • image_type: summer or winter, the names of the directories where the X and Y images are stored
  • image_dir: name of the main image directory, which holds all training and test images
  • image_size: resized, square image dimension (all images will be resized to this dim)
  • batch_size: number of images in one batch of data

The test data is strictly for feeding to our generators, later on, so we can visualize some generated samples on fixed, test data.

You can see that this function is also responsible for making sure our images are of the right, square size (128x128x3) and converted into Tensor image types.

It's suggested that you use the default values of these parameters.

Note: If you are trying this code on a different set of data, you may get better results with larger image_size and batch_size parameters. If you change the batch_size, make sure that you create complete batches in the training loop otherwise you may get an error when trying to save sample data.

In [2]:
def get_data_loader(image_type, image_dir='summer2winter_yosemite', 
                    image_size=128, batch_size=16, num_workers=0):
    """Returns training and test data loaders for a given image type, either 'summer' or 'winter'. 
       These images will be resized to 128x128x3, by default, converted into Tensors, and normalized.
    """
    
    # resize and normalize the images
    transform = transforms.Compose([transforms.Resize(image_size), # resize to 128x128
                                    transforms.ToTensor()])

    # get training and test directories
    image_path = './' + image_dir
    train_path = os.path.join(image_path, image_type)
    test_path = os.path.join(image_path, 'test_{}'.format(image_type))

    # define datasets using ImageFolder
    train_dataset = datasets.ImageFolder(train_path, transform)
    test_dataset = datasets.ImageFolder(test_path, transform)

    # create and return DataLoaders
    train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers)
    test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False, num_workers=num_workers)

    return train_loader, test_loader
In [3]:
# Create train and test dataloaders for images from the two domains X and Y
# image_type = directory names for our data
dataloader_X, test_dataloader_X = get_data_loader(image_type='summer')
dataloader_Y, test_dataloader_Y = get_data_loader(image_type='winter')

Display some Training Images

Below we provide a function imshow that reshape some given images and converts them to NumPy images so that they can be displayed by plt. This cell should display a grid that contains a batch of image data from set $X$.

In [4]:
# helper imshow function
def imshow(img):
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    

# get some images from X
dataiter = iter(dataloader_X)
# the "_" is a placeholder for no labels
images, _ = dataiter.next()

# show images
fig = plt.figure(figsize=(12, 8))
imshow(torchvision.utils.make_grid(images))

Next, let's visualize a batch of images from set $Y$.

In [5]:
# get some images from Y
dataiter = iter(dataloader_Y)
images, _ = dataiter.next()

# show images
fig = plt.figure(figsize=(12,8))
imshow(torchvision.utils.make_grid(images))

Pre-processing: scaling from -1 to 1

We need to do a bit of pre-processing; we know that the output of our tanh activated generator will contain pixel values in a range from -1 to 1, and so, we need to rescale our training images to a range of -1 to 1. (Right now, they are in a range from 0-1.)

In [6]:
# current range
img = images[0]

print('Min: ', img.min())
print('Max: ', img.max())
Min:  tensor(1.00000e-02 *
       1.9608)
Max:  tensor(0.9255)
In [7]:
# helper scale function
def scale(x, feature_range=(-1, 1)):
    ''' Scale takes in an image x and returns that image, scaled
       with a feature_range of pixel values from -1 to 1. 
       This function assumes that the input x is already scaled from 0-255.'''
    
    # scale from 0-1 to feature_range
    min, max = feature_range
    x = x * (max - min) + min
    return x
In [8]:
# scaled range
scaled_img = scale(img)

print('Scaled min: ', scaled_img.min())
print('Scaled max: ', scaled_img.max())
Scaled min:  tensor(-0.9608)
Scaled max:  tensor(0.8510)

Define the Model

A CycleGAN is made of two discriminator and two generator networks.

Discriminators

The discriminators, $D_X$ and $D_Y$, in this CycleGAN are convolutional neural networks that see an image and attempt to classify it as real or fake. In this case, real is indicated by an output close to 1 and fake as close to 0. The discriminators have the following architecture:

This network sees a 128x128x3 image, and passes it through 5 convolutional layers that downsample the image by a factor of 2. The first four convolutional layers have a BatchNorm and ReLu activation function applied to their output, and the last acts as a classification layer that outputs one value.

Convolutional Helper Function

To define the discriminators, we make use of this conv function, which creates a convolutional layer + an optional batch norm layer.

In [9]:
import torch.nn as nn
import torch.nn.functional as F

# helper conv function
def conv(in_channels, out_channels, kernel_size, stride=2, padding=1, batch_norm=True):
    """Creates a convolutional layer, with optional batch normalization.
    """
    layers = []
    conv_layer = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, 
                           kernel_size=kernel_size, stride=stride, padding=padding, bias=False)
    
    layers.append(conv_layer)

    if batch_norm:
        layers.append(nn.BatchNorm2d(out_channels))
    return nn.Sequential(*layers)

Define the Discriminator Architecture

Tthe __init__ function has the specified 5 layer conv net architecture. Both $D_X$ and $D_Y$ have the same architecture, so we only need to define one class, and later instantiate two discriminators.

It's recommended to use a kernel size of 4x4 and use that to determine the correct stride and padding size for each layer. This Stanford resource may also help in determining stride and padding sizes.

  • Define your convolutional layers in __init__
  • Then fill in the forward behavior of the network

The forward function defines how an input image moves through the discriminator, and the most important thing is to pass it through your convolutional layers in order, with a ReLu activation function applied to all but the last layer.

To reiterate, we do not apply a sigmoid activation function to the output, here, and that is because we are planning on using a squared error loss for training. And you can read more about this loss function, later in the notebook.

In [10]:
class Discriminator(nn.Module):
    
    def __init__(self, conv_dim=64):
        super(Discriminator, self).__init__()
        
        self.conv1 = conv(3, conv_dim, 4, batch_norm=False)       
        self.conv2 = conv(conv_dim, conv_dim * 2, 4)       
        self.conv3 = conv(conv_dim * 2, conv_dim * 4, 4)       
        self.conv4 = conv(conv_dim * 4, conv_dim * 8, 4)       
        self.conv5 = conv(conv_dim * 8, 1, 4, batch_norm=False)       


    def forward(self, x):
        
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        x = F.relu(self.conv3(x))
        x = F.relu(self.conv4(x))
        
        x = self.conv5(x)
        return x

Generators

The generators, G_XtoY and G_YtoX (sometimes called F), are made of an encoder, a conv net that is responsible for turning an image into a smaller feature representation, and a decoder, a transpose_conv net that is responsible for turning that representation into an transformed image. These generators, one from XtoY and one from YtoX, have the following architecture:

This network sees a 128x128x3 image, compresses it into a feature representation as it goes through three convolutional layers and reaches a series of residual blocks. It goes through a few (typically 6 or more) of these residual blocks, then it goes through three transpose convolutional layers (sometimes called de-conv layers) which upsample the output of the resnet blocks and create a new image!

Note that most of the convolutional and transpose-convolutional layers have BatchNorm and ReLu functions applied to their outputs with the exception of the final transpose convolutional layer, which has a tanh activation function applied to the output. Also, the residual blocks are made of convolutional and batch normalization layers, which we'll go over in more detail, next.


Residual Block Class

To define the generators, you're expected to define a ResidualBlock class which will help you connect the encoder and decoder portions of the generators. You might be wondering, what exactly is a Resnet block? It may sound familiar from something like ResNet50 for image classification, pictured below.

ResNet blocks rely on connecting the output of one layer with the input of an earlier layer. The motivation for this structure is as follows: very deep neural networks can be difficult to train. Deeper networks are more likely to have vanishing or exploding gradients and, therefore, have trouble reaching convergence; batch normalization helps with this a bit. However, during training, we often see that deep networks respond with a kind of training degradation. Essentially, the training accuracy stops improving and gets saturated at some point during training. In the worst cases, deep models would see their training accuracy actually worsen over time!

One solution to this problem is to use Resnet blocks that allow us to learn so-called residual functions as they are applied to layer inputs. You can read more about this proposed architecture in the paper, Deep Residual Learning for Image Recognition by Kaiming He et. al, and the below image is from that paper.

Residual Functions

Usually, when we create a deep learning model, the model (several layers with activations applied) is responsible for learning a mapping, M, from an input x to an output y.

M(x) = y (Equation 1)

Instead of learning a direct mapping from x to y, we can instead define a residual function

F(x) = M(x) - x

This looks at the difference between a mapping applied to x and the original input, x. F(x) is, typically, two convolutional layers + normalization layer and a ReLu in between. These convolutional layers should have the same number of inputs as outputs. This mapping can then be written as the following; a function of the residual function and the input x. The addition step creates a kind of loop that connects the input x to the output, y:

M(x) = F(x) + x (Equation 2) or

y = F(x) + x (Equation 3)

Optimizing a Residual Function

The idea is that it is easier to optimize this residual function F(x) than it is to optimize the original mapping M(x). Consider an example; what if we want y = x?

From our first, direct mapping equation, Equation 1, we could set M(x) = x but it is easier to solve the residual equation F(x) = 0, which, when plugged in to Equation 3, yields y = x.

Defining the ResidualBlock Class

To define the ResidualBlock class, we'll define residual functions (a series of layers), apply them to an input x and add them to that same input. This is defined just like any other neural network, with an __init__ function and the addition step in the forward function.

In our case, we define the residual block as:

  • Two convolutional layers with the same size input and output
  • Batch normalization applied to the outputs of the convolutional layers
  • A ReLu function on the output of the first convolutional layer

Then, in the forward function, add the input x to this residual block.

In [11]:
# residual block class
class ResidualBlock(nn.Module):
    """Defines a residual block.
       This adds an input x to a convolutional layer (applied to x) with the same size input and output.
       These blocks allow a model to learn an effective transformation from one domain to another.
    """
    def __init__(self, conv_dim):
        super(ResidualBlock, self).__init__()

        self.conv1 = conv(conv_dim, conv_dim, kernel_size=3, stride=1, padding=1, batch_norm=True)               
        self.conv2 = conv(conv_dim, conv_dim, kernel_size=3, stride=1, padding=1, batch_norm=True)               

    def forward(self, x):
        # apply a ReLu activation the outputs of the first layer
        # return a summed output, x + resnet_block(x)
        x = F.relu(self.conv1(x))
        x = x + self.conv2(x)
        
        return x
    
In [12]:
import torch.nn as nn
import torch.nn.functional as F

# helper block function
def blocks(conv_dim, number_of_blocks = 6):
    """Creates a residual block of size `conv_dim`
    """
    layers = []
    for layer in range(number_of_blocks):
        layers.append(ResidualBlock(conv_dim))

    return nn.Sequential(*layers)

Transpose Convolutional Helper Function

To define the generators, we use the above conv function, ResidualBlock class, and the below deconv helper function, which creates a transpose convolutional layer + an optional batchnorm layer.

In [13]:
# helper deconv function
def deconv(in_channels, out_channels, kernel_size, stride=2, padding=1, batch_norm=True):
    """Creates a transpose convolutional layer, with optional batch normalization.
    """
    layers = []
    # append transpose conv layer
    layers.append(nn.ConvTranspose2d(in_channels, out_channels, kernel_size, stride, padding, bias=False))
    # optional batch norm layer
    if batch_norm:
        layers.append(nn.BatchNorm2d(out_channels))
    return nn.Sequential(*layers)

Define the Generator Architecture

  • Complete the __init__ function with the specified 3 layer encoder convolutional net, a series of residual blocks (the number of which is given by n_res_blocks), and then a 3 layer decoder transpose convolutional net.
  • Then complete the forward function to define the forward behavior of the generators. Recall that the last layer has a tanh activation function.

Both $G_{XtoY}$ and $G_{YtoX}$ have the same architecture, so we only need to define one class, and later instantiate two generators.

In [14]:
class CycleGenerator(nn.Module):
    
    def __init__(self, conv_dim=64, n_res_blocks=6):
        super(CycleGenerator, self).__init__()

        # 1. Define the encoder part of the generator
        
        # initial convolutional layer given, below
        self.conv1 = conv(3, conv_dim, 4)
        self.conv2 = conv(conv_dim, conv_dim*2, 4)
        self.conv3 = conv(conv_dim*2, conv_dim*4, 4)

        # 2. Define the resnet part of the generator
        # Residual blocks
        self.blocks = blocks(conv_dim * 4, n_res_blocks)

        # 3. Define the decoder part of the generator
        # two transpose convolutional layers and a third that looks a lot like the initial conv layer
        self.deconv1 = deconv(conv_dim*4, conv_dim*2, 4)
        self.deconv2 = deconv(conv_dim*2, conv_dim, 4)
        # no batch norm on last layer
        self.deconv3 = deconv(conv_dim, 3, 4, batch_norm=False)

    def forward(self, x):
        """Given an image x, returns a transformed image."""
        # define feedforward behavior, applying activations as necessary

        out = F.relu(self.conv1(x))
        out = F.relu(self.conv2(out))
        out = F.relu(self.conv3(out))

        out = self.blocks(out)

        out = F.relu(self.deconv1(out))
        out = F.relu(self.deconv2(out))
        # tanh applied to last layer
        out = F.tanh(self.deconv3(out))

        return out

Create the complete network

Using the classes defined earlier, we can define the discriminators and generators necessary to create a complete CycleGAN. The given parameters should work for training.

First, create two discriminators, one for checking if $X$ sample images are real, and one for checking if $Y$ sample images are real. Then the generators. Instantiate two of them, one for transforming a painting into a realistic photo and one for transforming a photo into into a painting.

In [15]:
def create_model(g_conv_dim=64, d_conv_dim=64, n_res_blocks=6):
    """Builds the generators and discriminators."""
    
    # Instantiate generators
    G_XtoY = CycleGenerator(conv_dim=g_conv_dim, n_res_blocks=n_res_blocks)
    G_YtoX = CycleGenerator(conv_dim=g_conv_dim, n_res_blocks=n_res_blocks)
    # Instantiate discriminators
    D_X = Discriminator(conv_dim=d_conv_dim)
    D_Y = Discriminator(conv_dim=d_conv_dim)

    # move models to GPU, if available
    if torch.cuda.is_available():
        device = torch.device("cuda:0")
        G_XtoY.to(device)
        G_YtoX.to(device)
        D_X.to(device)
        D_Y.to(device)
        print('Models moved to GPU.')
    else:
        print('Only CPU available.')

    return G_XtoY, G_YtoX, D_X, D_Y
In [16]:
# call the function to get models
G_XtoY, G_YtoX, D_X, D_Y = create_model()
Models moved to GPU.

Check that you've implemented this correctly

The function create_model should return the two generator and two discriminator networks. After defining these discriminator and generator components, it's good practice to check our work. The easiest way to do this is to print out your model architecture and read through it to make sure the parameters are what you expected. The next cell will print out their architectures.

In [17]:
# helper function for printing the model architecture
def print_models(G_XtoY, G_YtoX, D_X, D_Y):
    """Prints model information for the generators and discriminators.
    """
    print("                     G_XtoY                    ")
    print("-----------------------------------------------")
    print(G_XtoY)
    print()

    print("                     G_YtoX                    ")
    print("-----------------------------------------------")
    print(G_YtoX)
    print()

    print("                      D_X                      ")
    print("-----------------------------------------------")
    print(D_X)
    print()

    print("                      D_Y                      ")
    print("-----------------------------------------------")
    print(D_Y)
    print()
    

# print all of the models
print_models(G_XtoY, G_YtoX, D_X, D_Y)
                     G_XtoY                    
-----------------------------------------------
CycleGenerator(
  (conv1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv2): Sequential(
    (0): Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv3): Sequential(
    (0): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (blocks): Sequential(
    (0): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (2): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (3): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (4): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (5): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (deconv1): Sequential(
    (0): ConvTranspose2d(256, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (deconv2): Sequential(
    (0): ConvTranspose2d(128, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (deconv3): Sequential(
    (0): ConvTranspose2d(64, 3, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
)

                     G_YtoX                    
-----------------------------------------------
CycleGenerator(
  (conv1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv2): Sequential(
    (0): Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv3): Sequential(
    (0): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (blocks): Sequential(
    (0): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (2): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (3): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (4): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (5): ResidualBlock(
      (conv1): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (conv2): Sequential(
        (0): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (deconv1): Sequential(
    (0): ConvTranspose2d(256, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (deconv2): Sequential(
    (0): ConvTranspose2d(128, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (deconv3): Sequential(
    (0): ConvTranspose2d(64, 3, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
)

                      D_X                      
-----------------------------------------------
Discriminator(
  (conv1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
  (conv2): Sequential(
    (0): Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv3): Sequential(
    (0): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv4): Sequential(
    (0): Conv2d(256, 512, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv5): Sequential(
    (0): Conv2d(512, 1, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
)

                      D_Y                      
-----------------------------------------------
Discriminator(
  (conv1): Sequential(
    (0): Conv2d(3, 64, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
  (conv2): Sequential(
    (0): Conv2d(64, 128, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv3): Sequential(
    (0): Conv2d(128, 256, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv4): Sequential(
    (0): Conv2d(256, 512, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
    (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  )
  (conv5): Sequential(
    (0): Conv2d(512, 1, kernel_size=(4, 4), stride=(2, 2), padding=(1, 1), bias=False)
  )
)

Discriminator and Generator Losses

Computing the discriminator and the generator losses are key to getting a CycleGAN to train.

Image from original paper by Jun-Yan Zhu et. al.

  • The CycleGAN contains two mapping functions $G: X \rightarrow Y$ and $F: Y \rightarrow X$, and associated adversarial discriminators $D_Y$ and $D_X$. (a) $D_Y$ encourages $G$ to translate $X$ into outputs indistinguishable from domain $Y$, and vice versa for $D_X$ and $F$.

  • To further regularize the mappings, we introduce two cycle consistency losses that capture the intuition that if we translate from one domain to the other and back again we should arrive at where we started. (b) Forward cycle-consistency loss and (c) backward cycle-consistency loss.

Least Squares GANs

We've seen that regular GANs treat the discriminator as a classifier with the sigmoid cross entropy loss function. However, this loss function may lead to the vanishing gradients problem during the learning process. To overcome such a problem, we'll use a least squares loss function for the discriminator. This structure is also referred to as a least squares GAN or LSGAN, and you can read the original paper on LSGANs, here. The authors show that LSGANs are able to generate higher quality images than regular GANs and that this loss type is a bit more stable during training!

Discriminator Losses

The discriminator losses will be mean squared errors between the output of the discriminator, given an image, and the target value, 0 or 1, depending on whether it should classify that image as fake or real. For example, for a real image, x, we can train $D_X$ by looking at how close it is to recognizing and image x as real using the mean squared error:

out_x = D_X(x)
real_err = torch.mean((out_x-1)**2)

Generator Losses

Calculating the generator losses will look somewhat similar to calculating the discriminator loss; there will still be steps in which you generate fake images that look like they belong to the set of $X$ images but are based on real images in set $Y$, and vice versa. You'll compute the "real loss" on those generated images by looking at the output of the discriminator as it's applied to these fake images; this time, your generator aims to make the discriminator classify these fake images as real images.

Cycle Consistency Loss

In addition to the adversarial losses, the generator loss terms will also include the cycle consistency loss. This loss is a measure of how good a reconstructed image is, when compared to an original image.

Say you have a fake, generated image, x_hat, and a real image, y. You can get a reconstructed y_hat by applying G_XtoY(x_hat) = y_hat and then check to see if this reconstruction y_hat and the orginal image y match. For this, we recommed calculating the L1 loss, which is an absolute difference, between reconstructed and real images. You may also choose to multiply this loss by some weight value lambda_weight to convey its importance.

The total generator loss will be the sum of the generator losses and the forward and backward cycle consistency losses.


Define Loss Functions

To help us calculate the discriminator and gnerator losses during training, let's define some helpful loss functions. Here, we'll define three.

  1. real_mse_loss that looks at the output of a discriminator and returns the error based on how close that output is to being classified as real. This should be a mean squared error.
  2. fake_mse_loss that looks at the output of a discriminator and returns the error based on how close that output is to being classified as fake. This should be a mean squared error.
  3. cycle_consistency_loss that looks at a set of real image and a set of reconstructed/generated images, and returns the mean absolute error between them. This has a lambda_weight parameter that will weight the mean absolute error in a batch.

It's recommended that you take a look at the original, CycleGAN paper to get a starting value for lambda_weight.

In [18]:
def real_mse_loss(D_out):
    # how close is the produced output from being "real"?
    real_err = torch.mean((D_out-1)**2)
    
    return real_err

def fake_mse_loss(D_out):
    # how close is the produced output from being "false"?
    real_err = torch.mean((D_out)**2)
    
    return real_err

def cycle_consistency_loss(real_im, reconstructed_im, lambda_weight):
    # calculate reconstruction loss 
    reconstruction_loss = torch.mean(torch.abs(real_im - reconstructed_im))
    
    # return weighted loss
    return lambda_weight * reconstruction_loss

Define the Optimizers

Next, let's define how this model will update its weights. This, like the GANs you may have seen before, uses Adam optimizers for the discriminator and generator. It's again recommended that you take a look at the original, CycleGAN paper to get starting hyperparameter values.

In [19]:
import torch.optim as optim

# hyperparams for Adam optimizers
lr=0.0002
beta1=0.5
beta2=0.999 

g_params = list(G_XtoY.parameters()) + list(G_YtoX.parameters())  # Get generator parameters

# Create optimizers for the generators and discriminators
g_optimizer = optim.Adam(g_params, lr, [beta1, beta2])
d_x_optimizer = optim.Adam(D_X.parameters(), lr, [beta1, beta2])
d_y_optimizer = optim.Adam(D_Y.parameters(), lr, [beta1, beta2])

Training a CycleGAN

When a CycleGAN trains, and sees one batch of real images from set $X$ and $Y$, it trains by performing the following steps:

Training the Discriminators

  1. Compute the discriminator $D_X$ loss on real images
  2. Generate fake images that look like domain $X$ based on real images in domain $Y$
  3. Compute the fake loss for $D_X$
  4. Compute the total loss and perform backpropagation and $D_X$ optimization
  5. Repeat steps 1-4 only with $D_Y$ and your domains switched!

Training the Generators

  1. Generate fake images that look like domain $X$ based on real images in domain $Y$
  2. Compute the generator loss based on how $D_X$ responds to fake $X$
  3. Generate reconstructed $\hat{Y}$ images based on the fake $X$ images generated in step 1
  4. Compute the cycle consistency loss by comparing the reconstructions with real $Y$ images
  5. Repeat steps 1-4 only swapping domains
  6. Add up all the generator and reconstruction losses and perform backpropagation + optimization

Saving Your Progress

A CycleGAN repeats its training process, alternating between training the discriminators and the generators, for a specified number of training iterations. You've been given code that will save some example generated images that the CycleGAN has learned to generate after a certain number of training iterations. Along with looking at the losses, these example generations should give you an idea of how well your network has trained.

Below, you may choose to keep all default parameters.

In [20]:
# import save code
from helpers import save_samples, checkpoint
In [21]:
# train the network
def training_loop(dataloader_X, dataloader_Y, test_dataloader_X, test_dataloader_Y, 
                  n_epochs=1000):
    
    print_every=10
    
    # keep track of losses over time
    losses = []

    test_iter_X = iter(test_dataloader_X)
    test_iter_Y = iter(test_dataloader_Y)

    # Get some fixed data from domains X and Y for sampling. These are images that are held
    # constant throughout training, that allow us to inspect the model's performance.
    fixed_X = test_iter_X.next()[0]
    fixed_Y = test_iter_Y.next()[0]
    fixed_X = scale(fixed_X) # make sure to scale to a range -1 to 1
    fixed_Y = scale(fixed_Y)

    # batches per epoch
    iter_X = iter(dataloader_X)
    iter_Y = iter(dataloader_Y)
    batches_per_epoch = min(len(iter_X), len(iter_Y))

    for epoch in range(1, n_epochs+1):

        # Reset iterators for each epoch
        if epoch % batches_per_epoch == 0:
            iter_X = iter(dataloader_X)
            iter_Y = iter(dataloader_Y)

        images_X, _ = iter_X.next()
        images_X = scale(images_X) # make sure to scale to a range -1 to 1

        images_Y, _ = iter_Y.next()
        images_Y = scale(images_Y)
        
        # move images to GPU if available (otherwise stay on CPU)
        device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
        images_X = images_X.to(device)
        images_Y = images_Y.to(device)


        # ============================================
        #            TRAIN THE DISCRIMINATORS
        # ============================================

        ##   First: D_X, real and fake loss components   ##
        
        d_x_optimizer.zero_grad()

        # 1. Compute the discriminator losses on real images
        out_x = D_X(images_X)
        D_X_real_loss = real_mse_loss(out_x)
        
        # 2. Generate fake images that look like domain X based on real images in domain Y
        fake_X = G_YtoX(images_Y)

        # 3. Compute the fake loss for D_X
        out_x = D_X(images_X)
        D_X_fake_loss = fake_mse_loss(out_x)
        
        # 4. Compute the total loss and perform backprop
        d_x_loss = D_X_real_loss + D_X_fake_loss
        d_x_loss.backward()
        d_x_optimizer.step()

        
        ##   Second: D_Y, real and fake loss components   ##
        
        d_y_optimizer.zero_grad()

        out_y = D_Y(images_Y)
        D_Y_real_loss = real_mse_loss(out_y)
        
        fake_Y = G_XtoY(images_X)

        out_y = D_Y(images_Y)
        D_Y_fake_loss = fake_mse_loss(out_y)
        
        d_y_loss = D_Y_real_loss + D_Y_fake_loss
        d_y_loss.backward()
        d_y_optimizer.step()        


        # =========================================
        #            TRAIN THE GENERATORS
        # =========================================

        ##    First: generate fake X images and reconstructed Y images    ##
        g_optimizer.zero_grad()

        # 1. Generate fake images that look like domain X based on real images in domain Y
        fake_X = G_YtoX(images_Y)

        # 2. Compute the generator loss based on domain X
        out_x = D_X(fake_X)
        g_YtoX_loss = real_mse_loss(out_x)

        # 3. Create a reconstructed y
        # 4. Compute the cycle consistency loss (the reconstruction loss)
        reconstructed_Y = G_XtoY(fake_X)
        reconstructed_y_loss = cycle_consistency_loss(images_Y, reconstructed_Y, lambda_weight=10)

        ##    Second: generate fake Y images and reconstructed X images    ##
        fake_Y = G_XtoY(images_X)

        out_y = D_Y(fake_Y)
        g_XtoY_loss = real_mse_loss(out_y)

        reconstructed_X = G_XtoY(fake_Y)
        reconstructed_x_loss = cycle_consistency_loss(images_X, reconstructed_X, lambda_weight=10)

        # 5. Add up all generator and reconstructed losses and perform backprop
        g_total_loss = g_XtoY_loss + g_YtoX_loss + reconstructed_y_loss + reconstructed_x_loss
        g_total_loss.backward()
        g_optimizer.step()
        
        # Print the log info
        if epoch % print_every == 0:
            # append real and fake discriminator losses and the generator loss
            losses.append((d_x_loss.item(), d_y_loss.item(), g_total_loss.item()))
            print('Epoch [{:5d}/{:5d}] | d_X_loss: {:6.4f} | d_Y_loss: {:6.4f} | g_total_loss: {:6.4f}'.format(
                    epoch, n_epochs, d_x_loss.item(), d_y_loss.item(), g_total_loss.item()))

            
        sample_every=100
        # Save the generated samples
        if epoch % sample_every == 0:
            G_YtoX.eval() # set generators to eval mode for sample generation
            G_XtoY.eval()
            save_samples(epoch, fixed_Y, fixed_X, G_YtoX, G_XtoY, batch_size=16)
            G_YtoX.train()
            G_XtoY.train()

        # uncomment these lines, if you want to save your model
        checkpoint_every=1000
         # Save the model parameters
        if epoch % checkpoint_every == 0:
               checkpoint(epoch, G_XtoY, G_YtoX, D_X, D_Y)

    return losses
In [23]:
n_epochs = 8000 # keep this small when testing if a model first works, then increase it to >=1000

losses = training_loop(dataloader_X, dataloader_Y, test_dataloader_X, test_dataloader_Y, n_epochs=n_epochs)
Epoch [   10/ 8000] | d_X_loss: 0.5121 | d_Y_loss: 0.5108 | g_total_loss: 5.0130
Epoch [   20/ 8000] | d_X_loss: 0.5087 | d_Y_loss: 0.5126 | g_total_loss: 5.0223
Epoch [   30/ 8000] | d_X_loss: 0.5108 | d_Y_loss: 0.5052 | g_total_loss: 4.7386
Epoch [   40/ 8000] | d_X_loss: 0.5036 | d_Y_loss: 0.5069 | g_total_loss: 4.4113
Epoch [   50/ 8000] | d_X_loss: 0.5044 | d_Y_loss: 0.5052 | g_total_loss: 5.1617
Epoch [   60/ 8000] | d_X_loss: 0.5040 | d_Y_loss: 0.5072 | g_total_loss: 4.3013
Epoch [   70/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5037 | g_total_loss: 4.0458
Epoch [   80/ 8000] | d_X_loss: 0.5044 | d_Y_loss: 0.5053 | g_total_loss: 4.1936
Epoch [   90/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5043 | g_total_loss: 4.2279
Epoch [  100/ 8000] | d_X_loss: 0.5140 | d_Y_loss: 0.5042 | g_total_loss: 4.0304
Saved samples_cyclegan/sample-000100-X-Y.png
Saved samples_cyclegan/sample-000100-Y-X.png
Epoch [  110/ 8000] | d_X_loss: 0.5046 | d_Y_loss: 0.5064 | g_total_loss: 4.1524
Epoch [  120/ 8000] | d_X_loss: 0.5378 | d_Y_loss: 0.5052 | g_total_loss: 4.1372
Epoch [  130/ 8000] | d_X_loss: 0.5115 | d_Y_loss: 0.5029 | g_total_loss: 3.8684
Epoch [  140/ 8000] | d_X_loss: 0.5062 | d_Y_loss: 0.5044 | g_total_loss: 4.1880
Epoch [  150/ 8000] | d_X_loss: 0.5138 | d_Y_loss: 0.5128 | g_total_loss: 3.8723
Epoch [  160/ 8000] | d_X_loss: 0.5046 | d_Y_loss: 0.5113 | g_total_loss: 3.7268
Epoch [  170/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5016 | g_total_loss: 3.8394
Epoch [  180/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5032 | g_total_loss: 3.6056
Epoch [  190/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5063 | g_total_loss: 3.6638
Epoch [  200/ 8000] | d_X_loss: 0.5194 | d_Y_loss: 0.5030 | g_total_loss: 3.8049
Saved samples_cyclegan/sample-000200-X-Y.png
Saved samples_cyclegan/sample-000200-Y-X.png
Epoch [  210/ 8000] | d_X_loss: 0.5089 | d_Y_loss: 0.5079 | g_total_loss: 3.7346
Epoch [  220/ 8000] | d_X_loss: 0.5087 | d_Y_loss: 0.5042 | g_total_loss: 3.5875
Epoch [  230/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5032 | g_total_loss: 3.2949
Epoch [  240/ 8000] | d_X_loss: 0.5042 | d_Y_loss: 0.5020 | g_total_loss: 3.6973
Epoch [  250/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5050 | g_total_loss: 3.4481
Epoch [  260/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5040 | g_total_loss: 3.3458
Epoch [  270/ 8000] | d_X_loss: 0.5063 | d_Y_loss: 0.5041 | g_total_loss: 3.2983
Epoch [  280/ 8000] | d_X_loss: 0.5040 | d_Y_loss: 0.5014 | g_total_loss: 3.5673
Epoch [  290/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5036 | g_total_loss: 3.2208
Epoch [  300/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5018 | g_total_loss: 3.1252
Saved samples_cyclegan/sample-000300-X-Y.png
Saved samples_cyclegan/sample-000300-Y-X.png
Epoch [  310/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5023 | g_total_loss: 3.3116
Epoch [  320/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5058 | g_total_loss: 3.1632
Epoch [  330/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5147 | g_total_loss: 3.1595
Epoch [  340/ 8000] | d_X_loss: 0.5031 | d_Y_loss: 0.5022 | g_total_loss: 3.6380
Epoch [  350/ 8000] | d_X_loss: 0.5142 | d_Y_loss: 0.5030 | g_total_loss: 3.5467
Epoch [  360/ 8000] | d_X_loss: 0.5063 | d_Y_loss: 0.5059 | g_total_loss: 2.9461
Epoch [  370/ 8000] | d_X_loss: 0.5086 | d_Y_loss: 0.5031 | g_total_loss: 3.0156
Epoch [  380/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5013 | g_total_loss: 2.9249
Epoch [  390/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5019 | g_total_loss: 3.1928
Epoch [  400/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5014 | g_total_loss: 3.2758
Saved samples_cyclegan/sample-000400-X-Y.png
Saved samples_cyclegan/sample-000400-Y-X.png
Epoch [  410/ 8000] | d_X_loss: 0.5045 | d_Y_loss: 0.5076 | g_total_loss: 3.2748
Epoch [  420/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5037 | g_total_loss: 3.3048
Epoch [  430/ 8000] | d_X_loss: 0.5066 | d_Y_loss: 0.5038 | g_total_loss: 3.2753
Epoch [  440/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5068 | g_total_loss: 3.0390
Epoch [  450/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5042 | g_total_loss: 3.0556
Epoch [  460/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5027 | g_total_loss: 2.7264
Epoch [  470/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5086 | g_total_loss: 2.8282
Epoch [  480/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5055 | g_total_loss: 2.9649
Epoch [  490/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5049 | g_total_loss: 2.9961
Epoch [  500/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5038 | g_total_loss: 3.3118
Saved samples_cyclegan/sample-000500-X-Y.png
Saved samples_cyclegan/sample-000500-Y-X.png
Epoch [  510/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5054 | g_total_loss: 4.0546
Epoch [  520/ 8000] | d_X_loss: 0.5062 | d_Y_loss: 0.5047 | g_total_loss: 3.2929
Epoch [  530/ 8000] | d_X_loss: 0.5038 | d_Y_loss: 0.5010 | g_total_loss: 3.0373
Epoch [  540/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5010 | g_total_loss: 3.4500
Epoch [  550/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5025 | g_total_loss: 3.1373
Epoch [  560/ 8000] | d_X_loss: 0.5080 | d_Y_loss: 0.5044 | g_total_loss: 3.5532
Epoch [  570/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5052 | g_total_loss: 3.1888
Epoch [  580/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5016 | g_total_loss: 3.3591
Epoch [  590/ 8000] | d_X_loss: 0.5041 | d_Y_loss: 0.5028 | g_total_loss: 3.4724
Epoch [  600/ 8000] | d_X_loss: 0.5146 | d_Y_loss: 0.5080 | g_total_loss: 3.4600
Saved samples_cyclegan/sample-000600-X-Y.png
Saved samples_cyclegan/sample-000600-Y-X.png
Epoch [  610/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5034 | g_total_loss: 3.0676
Epoch [  620/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5049 | g_total_loss: 3.3463
Epoch [  630/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5029 | g_total_loss: 2.8422
Epoch [  640/ 8000] | d_X_loss: 0.5130 | d_Y_loss: 0.5018 | g_total_loss: 2.6707
Epoch [  650/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5021 | g_total_loss: 3.0679
Epoch [  660/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5010 | g_total_loss: 2.7986
Epoch [  670/ 8000] | d_X_loss: 0.5089 | d_Y_loss: 0.5023 | g_total_loss: 3.2137
Epoch [  680/ 8000] | d_X_loss: 0.5095 | d_Y_loss: 0.5033 | g_total_loss: 2.8149
Epoch [  690/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5034 | g_total_loss: 2.8992
Epoch [  700/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5042 | g_total_loss: 2.9795
Saved samples_cyclegan/sample-000700-X-Y.png
Saved samples_cyclegan/sample-000700-Y-X.png
Epoch [  710/ 8000] | d_X_loss: 0.5062 | d_Y_loss: 0.5019 | g_total_loss: 2.9998
Epoch [  720/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5018 | g_total_loss: 2.9927
Epoch [  730/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5013 | g_total_loss: 2.7326
Epoch [  740/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5068 | g_total_loss: 3.2790
Epoch [  750/ 8000] | d_X_loss: 0.5040 | d_Y_loss: 0.5009 | g_total_loss: 2.6113
Epoch [  760/ 8000] | d_X_loss: 0.5051 | d_Y_loss: 0.5065 | g_total_loss: 2.7658
Epoch [  770/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5022 | g_total_loss: 2.5507
Epoch [  780/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5010 | g_total_loss: 2.8056
Epoch [  790/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5094 | g_total_loss: 2.7205
Epoch [  800/ 8000] | d_X_loss: 0.5056 | d_Y_loss: 0.5042 | g_total_loss: 2.7945
Saved samples_cyclegan/sample-000800-X-Y.png
Saved samples_cyclegan/sample-000800-Y-X.png
Epoch [  810/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5015 | g_total_loss: 2.9810
Epoch [  820/ 8000] | d_X_loss: 0.5034 | d_Y_loss: 0.5010 | g_total_loss: 2.9779
Epoch [  830/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5012 | g_total_loss: 2.9914
Epoch [  840/ 8000] | d_X_loss: 0.5041 | d_Y_loss: 0.5023 | g_total_loss: 3.0046
Epoch [  850/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5004 | g_total_loss: 2.7115
Epoch [  860/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5029 | g_total_loss: 2.5788
Epoch [  870/ 8000] | d_X_loss: 0.5073 | d_Y_loss: 0.5010 | g_total_loss: 2.5509
Epoch [  880/ 8000] | d_X_loss: 0.5047 | d_Y_loss: 0.5011 | g_total_loss: 2.6784
Epoch [  890/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5015 | g_total_loss: 2.8316
Epoch [  900/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5030 | g_total_loss: 3.1273
Saved samples_cyclegan/sample-000900-X-Y.png
Saved samples_cyclegan/sample-000900-Y-X.png
Epoch [  910/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5012 | g_total_loss: 2.7065
Epoch [  920/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5047 | g_total_loss: 3.0178
Epoch [  930/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5017 | g_total_loss: 2.7341
Epoch [  940/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5105 | g_total_loss: 2.7350
Epoch [  950/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5015 | g_total_loss: 2.8989
Epoch [  960/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5016 | g_total_loss: 3.2854
Epoch [  970/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5009 | g_total_loss: 2.7570
Epoch [  980/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5032 | g_total_loss: 2.7249
Epoch [  990/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5012 | g_total_loss: 2.6760
Epoch [ 1000/ 8000] | d_X_loss: 0.5062 | d_Y_loss: 0.5008 | g_total_loss: 3.2649
Saved samples_cyclegan/sample-001000-X-Y.png
Saved samples_cyclegan/sample-001000-Y-X.png
Epoch [ 1010/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5013 | g_total_loss: 2.9366
Epoch [ 1020/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5009 | g_total_loss: 2.6515
Epoch [ 1030/ 8000] | d_X_loss: 0.5068 | d_Y_loss: 0.5037 | g_total_loss: 2.8758
Epoch [ 1040/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5009 | g_total_loss: 2.9121
Epoch [ 1050/ 8000] | d_X_loss: 0.5037 | d_Y_loss: 0.5010 | g_total_loss: 3.1575
Epoch [ 1060/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5035 | g_total_loss: 3.2017
Epoch [ 1070/ 8000] | d_X_loss: 0.5029 | d_Y_loss: 0.5016 | g_total_loss: 2.8336
Epoch [ 1080/ 8000] | d_X_loss: 0.5050 | d_Y_loss: 0.5020 | g_total_loss: 2.8262
Epoch [ 1090/ 8000] | d_X_loss: 0.5056 | d_Y_loss: 0.5007 | g_total_loss: 2.6565
Epoch [ 1100/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5027 | g_total_loss: 2.7639
Saved samples_cyclegan/sample-001100-X-Y.png
Saved samples_cyclegan/sample-001100-Y-X.png
Epoch [ 1110/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5006 | g_total_loss: 2.8447
Epoch [ 1120/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5016 | g_total_loss: 2.8908
Epoch [ 1130/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5030 | g_total_loss: 2.6879
Epoch [ 1140/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5005 | g_total_loss: 2.7332
Epoch [ 1150/ 8000] | d_X_loss: 0.5052 | d_Y_loss: 0.5067 | g_total_loss: 3.1769
Epoch [ 1160/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5238 | g_total_loss: 2.9037
Epoch [ 1170/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5021 | g_total_loss: 2.4712
Epoch [ 1180/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5026 | g_total_loss: 2.8932
Epoch [ 1190/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5016 | g_total_loss: 2.7551
Epoch [ 1200/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5022 | g_total_loss: 2.5958
Saved samples_cyclegan/sample-001200-X-Y.png
Saved samples_cyclegan/sample-001200-Y-X.png
Epoch [ 1210/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5081 | g_total_loss: 2.8830
Epoch [ 1220/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5205 | g_total_loss: 3.0055
Epoch [ 1230/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5009 | g_total_loss: 2.9608
Epoch [ 1240/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5015 | g_total_loss: 2.4764
Epoch [ 1250/ 8000] | d_X_loss: 0.5064 | d_Y_loss: 0.5005 | g_total_loss: 3.0053
Epoch [ 1260/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5008 | g_total_loss: 2.9870
Epoch [ 1270/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5004 | g_total_loss: 2.7301
Epoch [ 1280/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5007 | g_total_loss: 3.3129
Epoch [ 1290/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5051 | g_total_loss: 2.6436
Epoch [ 1300/ 8000] | d_X_loss: 0.5040 | d_Y_loss: 0.5004 | g_total_loss: 2.5720
Saved samples_cyclegan/sample-001300-X-Y.png
Saved samples_cyclegan/sample-001300-Y-X.png
Epoch [ 1310/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5008 | g_total_loss: 2.4982
Epoch [ 1320/ 8000] | d_X_loss: 0.5125 | d_Y_loss: 0.5008 | g_total_loss: 2.7450
Epoch [ 1330/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5079 | g_total_loss: 2.9982
Epoch [ 1340/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5010 | g_total_loss: 2.9625
Epoch [ 1350/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5008 | g_total_loss: 2.8085
Epoch [ 1360/ 8000] | d_X_loss: 0.5060 | d_Y_loss: 0.5120 | g_total_loss: 2.7691
Epoch [ 1370/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5005 | g_total_loss: 2.6372
Epoch [ 1380/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5041 | g_total_loss: 2.7613
Epoch [ 1390/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5034 | g_total_loss: 2.5861
Epoch [ 1400/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5008 | g_total_loss: 2.6813
Saved samples_cyclegan/sample-001400-X-Y.png
Saved samples_cyclegan/sample-001400-Y-X.png
Epoch [ 1410/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5005 | g_total_loss: 2.7582
Epoch [ 1420/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5021 | g_total_loss: 2.6532
Epoch [ 1430/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5004 | g_total_loss: 2.5196
Epoch [ 1440/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5004 | g_total_loss: 2.5992
Epoch [ 1450/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5017 | g_total_loss: 2.6345
Epoch [ 1460/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5010 | g_total_loss: 2.9458
Epoch [ 1470/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5014 | g_total_loss: 2.9020
Epoch [ 1480/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5014 | g_total_loss: 2.4978
Epoch [ 1490/ 8000] | d_X_loss: 0.5065 | d_Y_loss: 0.5024 | g_total_loss: 3.2550
Epoch [ 1500/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5006 | g_total_loss: 2.5415
Saved samples_cyclegan/sample-001500-X-Y.png
Saved samples_cyclegan/sample-001500-Y-X.png
Epoch [ 1510/ 8000] | d_X_loss: 0.5177 | d_Y_loss: 0.5053 | g_total_loss: 2.4119
Epoch [ 1520/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5014 | g_total_loss: 3.0154
Epoch [ 1530/ 8000] | d_X_loss: 0.5048 | d_Y_loss: 0.5010 | g_total_loss: 2.7816
Epoch [ 1540/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5009 | g_total_loss: 2.9547
Epoch [ 1550/ 8000] | d_X_loss: 0.5035 | d_Y_loss: 0.5036 | g_total_loss: 2.3357
Epoch [ 1560/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5024 | g_total_loss: 2.9730
Epoch [ 1570/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5055 | g_total_loss: 3.1259
Epoch [ 1580/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5023 | g_total_loss: 2.7000
Epoch [ 1590/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5039 | g_total_loss: 2.7778
Epoch [ 1600/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5004 | g_total_loss: 2.5595
Saved samples_cyclegan/sample-001600-X-Y.png
Saved samples_cyclegan/sample-001600-Y-X.png
Epoch [ 1610/ 8000] | d_X_loss: 0.5125 | d_Y_loss: 0.5021 | g_total_loss: 2.5118
Epoch [ 1620/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5005 | g_total_loss: 2.8252
Epoch [ 1630/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5031 | g_total_loss: 2.5485
Epoch [ 1640/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5008 | g_total_loss: 2.5866
Epoch [ 1650/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5018 | g_total_loss: 2.7107
Epoch [ 1660/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5007 | g_total_loss: 2.2051
Epoch [ 1670/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5016 | g_total_loss: 2.5337
Epoch [ 1680/ 8000] | d_X_loss: 0.5097 | d_Y_loss: 0.5006 | g_total_loss: 2.4813
Epoch [ 1690/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5006 | g_total_loss: 2.3994
Epoch [ 1700/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5005 | g_total_loss: 2.6339
Saved samples_cyclegan/sample-001700-X-Y.png
Saved samples_cyclegan/sample-001700-Y-X.png
Epoch [ 1710/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5006 | g_total_loss: 2.6733
Epoch [ 1720/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5003 | g_total_loss: 2.4847
Epoch [ 1730/ 8000] | d_X_loss: 0.5037 | d_Y_loss: 0.5008 | g_total_loss: 2.6035
Epoch [ 1740/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5010 | g_total_loss: 2.8680
Epoch [ 1750/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5036 | g_total_loss: 2.7029
Epoch [ 1760/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5012 | g_total_loss: 2.8930
Epoch [ 1770/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5995 | g_total_loss: 2.4712
Epoch [ 1780/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5024 | g_total_loss: 2.9835
Epoch [ 1790/ 8000] | d_X_loss: 0.5043 | d_Y_loss: 0.5019 | g_total_loss: 2.4316
Epoch [ 1800/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5019 | g_total_loss: 2.6200
Saved samples_cyclegan/sample-001800-X-Y.png
Saved samples_cyclegan/sample-001800-Y-X.png
Epoch [ 1810/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5010 | g_total_loss: 2.5776
Epoch [ 1820/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5005 | g_total_loss: 2.6402
Epoch [ 1830/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5011 | g_total_loss: 2.6653
Epoch [ 1840/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5005 | g_total_loss: 2.4760
Epoch [ 1850/ 8000] | d_X_loss: 0.5066 | d_Y_loss: 0.5018 | g_total_loss: 2.7312
Epoch [ 1860/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5014 | g_total_loss: 2.9621
Epoch [ 1870/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5032 | g_total_loss: 2.5668
Epoch [ 1880/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5050 | g_total_loss: 2.5029
Epoch [ 1890/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5077 | g_total_loss: 3.0684
Epoch [ 1900/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5030 | g_total_loss: 2.2592
Saved samples_cyclegan/sample-001900-X-Y.png
Saved samples_cyclegan/sample-001900-Y-X.png
Epoch [ 1910/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5011 | g_total_loss: 2.4995
Epoch [ 1920/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5018 | g_total_loss: 2.8248
Epoch [ 1930/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5065 | g_total_loss: 2.6955
Epoch [ 1940/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.7160
Epoch [ 1950/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5015 | g_total_loss: 2.5620
Epoch [ 1960/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5016 | g_total_loss: 2.6464
Epoch [ 1970/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5051 | g_total_loss: 2.2883
Epoch [ 1980/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5008 | g_total_loss: 2.3696
Epoch [ 1990/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5052 | g_total_loss: 2.9836
Epoch [ 2000/ 8000] | d_X_loss: 0.5036 | d_Y_loss: 0.5005 | g_total_loss: 2.7755
Saved samples_cyclegan/sample-002000-X-Y.png
Saved samples_cyclegan/sample-002000-Y-X.png
Epoch [ 2010/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5011 | g_total_loss: 2.6345
Epoch [ 2020/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5010 | g_total_loss: 2.5837
Epoch [ 2030/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5015 | g_total_loss: 2.4883
Epoch [ 2040/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5009 | g_total_loss: 2.4186
Epoch [ 2050/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5004 | g_total_loss: 2.3644
Epoch [ 2060/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5010 | g_total_loss: 2.4212
Epoch [ 2070/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5003 | g_total_loss: 2.8900
Epoch [ 2080/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5008 | g_total_loss: 2.6910
Epoch [ 2090/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5008 | g_total_loss: 2.3676
Epoch [ 2100/ 8000] | d_X_loss: 0.5046 | d_Y_loss: 0.5005 | g_total_loss: 2.7089
Saved samples_cyclegan/sample-002100-X-Y.png
Saved samples_cyclegan/sample-002100-Y-X.png
Epoch [ 2110/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5012 | g_total_loss: 2.5594
Epoch [ 2120/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5003 | g_total_loss: 2.4460
Epoch [ 2130/ 8000] | d_X_loss: 0.5217 | d_Y_loss: 0.5005 | g_total_loss: 2.3063
Epoch [ 2140/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5018 | g_total_loss: 3.0424
Epoch [ 2150/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5009 | g_total_loss: 2.3587
Epoch [ 2160/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5006 | g_total_loss: 2.5193
Epoch [ 2170/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.2057
Epoch [ 2180/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5028 | g_total_loss: 3.0441
Epoch [ 2190/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5007 | g_total_loss: 2.9203
Epoch [ 2200/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5005 | g_total_loss: 2.4874
Saved samples_cyclegan/sample-002200-X-Y.png
Saved samples_cyclegan/sample-002200-Y-X.png
Epoch [ 2210/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5005 | g_total_loss: 2.4888
Epoch [ 2220/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5023 | g_total_loss: 2.6431
Epoch [ 2230/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5006 | g_total_loss: 2.5163
Epoch [ 2240/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5005 | g_total_loss: 2.6587
Epoch [ 2250/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5011 | g_total_loss: 2.4205
Epoch [ 2260/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5020 | g_total_loss: 2.5432
Epoch [ 2270/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.4276
Epoch [ 2280/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5007 | g_total_loss: 2.4775
Epoch [ 2290/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5011 | g_total_loss: 2.2970
Epoch [ 2300/ 8000] | d_X_loss: 0.5099 | d_Y_loss: 0.5014 | g_total_loss: 2.4118
Saved samples_cyclegan/sample-002300-X-Y.png
Saved samples_cyclegan/sample-002300-Y-X.png
Epoch [ 2310/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5005 | g_total_loss: 2.6595
Epoch [ 2320/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.2686
Epoch [ 2330/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5017 | g_total_loss: 2.6153
Epoch [ 2340/ 8000] | d_X_loss: 0.5074 | d_Y_loss: 0.5008 | g_total_loss: 2.4357
Epoch [ 2350/ 8000] | d_X_loss: 0.5134 | d_Y_loss: 0.5012 | g_total_loss: 2.7448
Epoch [ 2360/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5010 | g_total_loss: 2.3670
Epoch [ 2370/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.3988
Epoch [ 2380/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5014 | g_total_loss: 2.3667
Epoch [ 2390/ 8000] | d_X_loss: 0.5039 | d_Y_loss: 0.5005 | g_total_loss: 2.5619
Epoch [ 2400/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5041 | g_total_loss: 2.1867
Saved samples_cyclegan/sample-002400-X-Y.png
Saved samples_cyclegan/sample-002400-Y-X.png
Epoch [ 2410/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5002 | g_total_loss: 2.3264
Epoch [ 2420/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5015 | g_total_loss: 2.7411
Epoch [ 2430/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5009 | g_total_loss: 2.5599
Epoch [ 2440/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5053 | g_total_loss: 2.6952
Epoch [ 2450/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5036 | g_total_loss: 2.6225
Epoch [ 2460/ 8000] | d_X_loss: 0.5097 | d_Y_loss: 0.5016 | g_total_loss: 2.5263
Epoch [ 2470/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5018 | g_total_loss: 2.6438
Epoch [ 2480/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5013 | g_total_loss: 2.3776
Epoch [ 2490/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5011 | g_total_loss: 2.3087
Epoch [ 2500/ 8000] | d_X_loss: 0.5029 | d_Y_loss: 0.5026 | g_total_loss: 3.1716
Saved samples_cyclegan/sample-002500-X-Y.png
Saved samples_cyclegan/sample-002500-Y-X.png
Epoch [ 2510/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5045 | g_total_loss: 2.4259
Epoch [ 2520/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5008 | g_total_loss: 2.3927
Epoch [ 2530/ 8000] | d_X_loss: 0.5048 | d_Y_loss: 0.5005 | g_total_loss: 2.3533
Epoch [ 2540/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5016 | g_total_loss: 2.3216
Epoch [ 2550/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5003 | g_total_loss: 2.6455
Epoch [ 2560/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5010 | g_total_loss: 2.3762
Epoch [ 2570/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5009 | g_total_loss: 2.7657
Epoch [ 2580/ 8000] | d_X_loss: 0.5072 | d_Y_loss: 0.5007 | g_total_loss: 2.4689
Epoch [ 2590/ 8000] | d_X_loss: 0.5034 | d_Y_loss: 0.5015 | g_total_loss: 2.4399
Epoch [ 2600/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5020 | g_total_loss: 2.3510
Saved samples_cyclegan/sample-002600-X-Y.png
Saved samples_cyclegan/sample-002600-Y-X.png
Epoch [ 2610/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.5193
Epoch [ 2620/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.5668
Epoch [ 2630/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5016 | g_total_loss: 2.5191
Epoch [ 2640/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5006 | g_total_loss: 2.5201
Epoch [ 2650/ 8000] | d_X_loss: 0.5069 | d_Y_loss: 0.5009 | g_total_loss: 2.8256
Epoch [ 2660/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5006 | g_total_loss: 2.9291
Epoch [ 2670/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5026 | g_total_loss: 2.1632
Epoch [ 2680/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5008 | g_total_loss: 2.2935
Epoch [ 2690/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5042 | g_total_loss: 2.2302
Epoch [ 2700/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5013 | g_total_loss: 2.5058
Saved samples_cyclegan/sample-002700-X-Y.png
Saved samples_cyclegan/sample-002700-Y-X.png
Epoch [ 2710/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5006 | g_total_loss: 2.2384
Epoch [ 2720/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.4608
Epoch [ 2730/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5017 | g_total_loss: 2.8965
Epoch [ 2740/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5006 | g_total_loss: 2.3854
Epoch [ 2750/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5013 | g_total_loss: 2.5061
Epoch [ 2760/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5009 | g_total_loss: 2.3793
Epoch [ 2770/ 8000] | d_X_loss: 0.5042 | d_Y_loss: 0.5026 | g_total_loss: 2.6326
Epoch [ 2780/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5004 | g_total_loss: 2.3723
Epoch [ 2790/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5010 | g_total_loss: 2.1455
Epoch [ 2800/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5005 | g_total_loss: 2.4472
Saved samples_cyclegan/sample-002800-X-Y.png
Saved samples_cyclegan/sample-002800-Y-X.png
Epoch [ 2810/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5052 | g_total_loss: 2.2099
Epoch [ 2820/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5033 | g_total_loss: 2.2492
Epoch [ 2830/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5015 | g_total_loss: 2.1650
Epoch [ 2840/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5008 | g_total_loss: 2.5525
Epoch [ 2850/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5007 | g_total_loss: 2.4337
Epoch [ 2860/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5008 | g_total_loss: 2.4987
Epoch [ 2870/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5006 | g_total_loss: 2.1411
Epoch [ 2880/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.4275
Epoch [ 2890/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5004 | g_total_loss: 2.2864
Epoch [ 2900/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5003 | g_total_loss: 2.5489
Saved samples_cyclegan/sample-002900-X-Y.png
Saved samples_cyclegan/sample-002900-Y-X.png
Epoch [ 2910/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5012 | g_total_loss: 2.4190
Epoch [ 2920/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5005 | g_total_loss: 2.4986
Epoch [ 2930/ 8000] | d_X_loss: 0.5062 | d_Y_loss: 0.5007 | g_total_loss: 2.5760
Epoch [ 2940/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5006 | g_total_loss: 2.2932
Epoch [ 2950/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.4493
Epoch [ 2960/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5004 | g_total_loss: 2.1492
Epoch [ 2970/ 8000] | d_X_loss: 0.5130 | d_Y_loss: 0.5014 | g_total_loss: 2.2210
Epoch [ 2980/ 8000] | d_X_loss: 0.5037 | d_Y_loss: 0.5010 | g_total_loss: 2.5783
Epoch [ 2990/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5006 | g_total_loss: 2.2376
Epoch [ 3000/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5009 | g_total_loss: 2.2864
Saved samples_cyclegan/sample-003000-X-Y.png
Saved samples_cyclegan/sample-003000-Y-X.png
Epoch [ 3010/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.4469
Epoch [ 3020/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5017 | g_total_loss: 2.2109
Epoch [ 3030/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5007 | g_total_loss: 2.2075
Epoch [ 3040/ 8000] | d_X_loss: 0.5043 | d_Y_loss: 0.5002 | g_total_loss: 2.6067
Epoch [ 3050/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2456
Epoch [ 3060/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5004 | g_total_loss: 2.3196
Epoch [ 3070/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5003 | g_total_loss: 2.2562
Epoch [ 3080/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.8638
Epoch [ 3090/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5016 | g_total_loss: 2.2699
Epoch [ 3100/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5010 | g_total_loss: 2.5777
Saved samples_cyclegan/sample-003100-X-Y.png
Saved samples_cyclegan/sample-003100-Y-X.png
Epoch [ 3110/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5006 | g_total_loss: 2.8080
Epoch [ 3120/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5005 | g_total_loss: 2.3534
Epoch [ 3130/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5004 | g_total_loss: 2.6955
Epoch [ 3140/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5029 | g_total_loss: 2.2320
Epoch [ 3150/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5004 | g_total_loss: 2.1474
Epoch [ 3160/ 8000] | d_X_loss: 0.5031 | d_Y_loss: 0.5003 | g_total_loss: 2.7337
Epoch [ 3170/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5007 | g_total_loss: 2.5871
Epoch [ 3180/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5004 | g_total_loss: 1.9625
Epoch [ 3190/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5006 | g_total_loss: 2.1251
Epoch [ 3200/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5028 | g_total_loss: 2.2393
Saved samples_cyclegan/sample-003200-X-Y.png
Saved samples_cyclegan/sample-003200-Y-X.png
Epoch [ 3210/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5003 | g_total_loss: 2.3518
Epoch [ 3220/ 8000] | d_X_loss: 0.5038 | d_Y_loss: 0.5002 | g_total_loss: 2.1300
Epoch [ 3230/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5024 | g_total_loss: 2.5330
Epoch [ 3240/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5014 | g_total_loss: 2.3551
Epoch [ 3250/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5006 | g_total_loss: 2.3735
Epoch [ 3260/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5011 | g_total_loss: 2.1317
Epoch [ 3270/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5040 | g_total_loss: 2.3392
Epoch [ 3280/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2690
Epoch [ 3290/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5005 | g_total_loss: 2.3616
Epoch [ 3300/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5004 | g_total_loss: 2.2731
Saved samples_cyclegan/sample-003300-X-Y.png
Saved samples_cyclegan/sample-003300-Y-X.png
Epoch [ 3310/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5005 | g_total_loss: 2.3670
Epoch [ 3320/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5006 | g_total_loss: 2.5596
Epoch [ 3330/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5009 | g_total_loss: 2.4178
Epoch [ 3340/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5009 | g_total_loss: 2.2792
Epoch [ 3350/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.3141
Epoch [ 3360/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5011 | g_total_loss: 2.4047
Epoch [ 3370/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5009 | g_total_loss: 2.3772
Epoch [ 3380/ 8000] | d_X_loss: 0.5073 | d_Y_loss: 0.5006 | g_total_loss: 2.2951
Epoch [ 3390/ 8000] | d_X_loss: 0.5034 | d_Y_loss: 0.5005 | g_total_loss: 2.3673
Epoch [ 3400/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5006 | g_total_loss: 2.1375
Saved samples_cyclegan/sample-003400-X-Y.png
Saved samples_cyclegan/sample-003400-Y-X.png
Epoch [ 3410/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5019 | g_total_loss: 2.5375
Epoch [ 3420/ 8000] | d_X_loss: 0.5077 | d_Y_loss: 0.5005 | g_total_loss: 2.1906
Epoch [ 3430/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5005 | g_total_loss: 2.4343
Epoch [ 3440/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5003 | g_total_loss: 2.4206
Epoch [ 3450/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5012 | g_total_loss: 2.2908
Epoch [ 3460/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5013 | g_total_loss: 2.2615
Epoch [ 3470/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5022 | g_total_loss: 2.2209
Epoch [ 3480/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.4977
Epoch [ 3490/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5014 | g_total_loss: 2.1924
Epoch [ 3500/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5007 | g_total_loss: 2.3041
Saved samples_cyclegan/sample-003500-X-Y.png
Saved samples_cyclegan/sample-003500-Y-X.png
Epoch [ 3510/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5017 | g_total_loss: 2.6461
Epoch [ 3520/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5007 | g_total_loss: 2.6121
Epoch [ 3530/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5011 | g_total_loss: 2.5071
Epoch [ 3540/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5008 | g_total_loss: 2.1961
Epoch [ 3550/ 8000] | d_X_loss: 0.5069 | d_Y_loss: 0.5022 | g_total_loss: 3.0497
Epoch [ 3560/ 8000] | d_X_loss: 0.5118 | d_Y_loss: 0.5004 | g_total_loss: 2.5732
Epoch [ 3570/ 8000] | d_X_loss: 0.5054 | d_Y_loss: 0.5002 | g_total_loss: 2.7749
Epoch [ 3580/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5004 | g_total_loss: 2.4854
Epoch [ 3590/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5011 | g_total_loss: 2.5960
Epoch [ 3600/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5002 | g_total_loss: 2.6182
Saved samples_cyclegan/sample-003600-X-Y.png
Saved samples_cyclegan/sample-003600-Y-X.png
Epoch [ 3610/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5007 | g_total_loss: 2.5100
Epoch [ 3620/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5006 | g_total_loss: 2.7104
Epoch [ 3630/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5002 | g_total_loss: 2.8535
Epoch [ 3640/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5008 | g_total_loss: 2.6417
Epoch [ 3650/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5093 | g_total_loss: 2.5093
Epoch [ 3660/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5020 | g_total_loss: 2.3580
Epoch [ 3670/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5006 | g_total_loss: 2.4936
Epoch [ 3680/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5008 | g_total_loss: 2.3931
Epoch [ 3690/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5015 | g_total_loss: 2.5783
Epoch [ 3700/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5006 | g_total_loss: 2.4478
Saved samples_cyclegan/sample-003700-X-Y.png
Saved samples_cyclegan/sample-003700-Y-X.png
Epoch [ 3710/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.4111
Epoch [ 3720/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5033 | g_total_loss: 3.0112
Epoch [ 3730/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5011 | g_total_loss: 2.7167
Epoch [ 3740/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5976 | g_total_loss: 3.1362
Epoch [ 3750/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5113 | g_total_loss: 2.4580
Epoch [ 3760/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5039 | g_total_loss: 2.3302
Epoch [ 3770/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5046 | g_total_loss: 2.6074
Epoch [ 3780/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5040 | g_total_loss: 2.8571
Epoch [ 3790/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5040 | g_total_loss: 2.6535
Epoch [ 3800/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5083 | g_total_loss: 3.0385
Saved samples_cyclegan/sample-003800-X-Y.png
Saved samples_cyclegan/sample-003800-Y-X.png
Epoch [ 3810/ 8000] | d_X_loss: 0.5031 | d_Y_loss: 0.5020 | g_total_loss: 2.1868
Epoch [ 3820/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5006 | g_total_loss: 2.3795
Epoch [ 3830/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5052 | g_total_loss: 2.5711
Epoch [ 3840/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5106 | g_total_loss: 2.2930
Epoch [ 3850/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5017 | g_total_loss: 2.2353
Epoch [ 3860/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5049 | g_total_loss: 2.3835
Epoch [ 3870/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5018 | g_total_loss: 2.8591
Epoch [ 3880/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.2814
Epoch [ 3890/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5020 | g_total_loss: 2.6187
Epoch [ 3900/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5009 | g_total_loss: 2.2523
Saved samples_cyclegan/sample-003900-X-Y.png
Saved samples_cyclegan/sample-003900-Y-X.png
Epoch [ 3910/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5014 | g_total_loss: 2.4627
Epoch [ 3920/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5028 | g_total_loss: 2.6529
Epoch [ 3930/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5024 | g_total_loss: 2.4609
Epoch [ 3940/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5005 | g_total_loss: 2.5259
Epoch [ 3950/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5081 | g_total_loss: 2.5595
Epoch [ 3960/ 8000] | d_X_loss: 0.5055 | d_Y_loss: 0.5010 | g_total_loss: 2.8063
Epoch [ 3970/ 8000] | d_X_loss: 0.5080 | d_Y_loss: 0.5007 | g_total_loss: 2.5915
Epoch [ 3980/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5101 | g_total_loss: 2.5238
Epoch [ 3990/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5018 | g_total_loss: 2.7201
Epoch [ 4000/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5003 | g_total_loss: 2.3058
Saved samples_cyclegan/sample-004000-X-Y.png
Saved samples_cyclegan/sample-004000-Y-X.png
Epoch [ 4010/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5004 | g_total_loss: 2.5991
Epoch [ 4020/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5005 | g_total_loss: 2.6675
Epoch [ 4030/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5004 | g_total_loss: 2.7006
Epoch [ 4040/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.6762
Epoch [ 4050/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5013 | g_total_loss: 2.3963
Epoch [ 4060/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5011 | g_total_loss: 2.6091
Epoch [ 4070/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.5229
Epoch [ 4080/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.1994
Epoch [ 4090/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.4665
Epoch [ 4100/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.4953
Saved samples_cyclegan/sample-004100-X-Y.png
Saved samples_cyclegan/sample-004100-Y-X.png
Epoch [ 4110/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.8965
Epoch [ 4120/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5004 | g_total_loss: 2.7793
Epoch [ 4130/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.4386
Epoch [ 4140/ 8000] | d_X_loss: 0.5036 | d_Y_loss: 0.5005 | g_total_loss: 2.2301
Epoch [ 4150/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5007 | g_total_loss: 2.5563
Epoch [ 4160/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.5040
Epoch [ 4170/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5003 | g_total_loss: 2.2476
Epoch [ 4180/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5016 | g_total_loss: 2.2861
Epoch [ 4190/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5007 | g_total_loss: 2.7438
Epoch [ 4200/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5007 | g_total_loss: 2.4009
Saved samples_cyclegan/sample-004200-X-Y.png
Saved samples_cyclegan/sample-004200-Y-X.png
Epoch [ 4210/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5005 | g_total_loss: 2.3393
Epoch [ 4220/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.2104
Epoch [ 4230/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5002 | g_total_loss: 2.3546
Epoch [ 4240/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.2611
Epoch [ 4250/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.4114
Epoch [ 4260/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5009 | g_total_loss: 2.2590
Epoch [ 4270/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5007 | g_total_loss: 2.5350
Epoch [ 4280/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5008 | g_total_loss: 2.5837
Epoch [ 4290/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5003 | g_total_loss: 2.4905
Epoch [ 4300/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5003 | g_total_loss: 2.3509
Saved samples_cyclegan/sample-004300-X-Y.png
Saved samples_cyclegan/sample-004300-Y-X.png
Epoch [ 4310/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.3786
Epoch [ 4320/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.3987
Epoch [ 4330/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5008 | g_total_loss: 3.0996
Epoch [ 4340/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5007 | g_total_loss: 2.4343
Epoch [ 4350/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5007 | g_total_loss: 2.5129
Epoch [ 4360/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5001 | g_total_loss: 2.1620
Epoch [ 4370/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.3496
Epoch [ 4380/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5002 | g_total_loss: 2.4656
Epoch [ 4390/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.3397
Epoch [ 4400/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5005 | g_total_loss: 2.4819
Saved samples_cyclegan/sample-004400-X-Y.png
Saved samples_cyclegan/sample-004400-Y-X.png
Epoch [ 4410/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5002 | g_total_loss: 2.4742
Epoch [ 4420/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5005 | g_total_loss: 2.3423
Epoch [ 4430/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5007 | g_total_loss: 2.2510
Epoch [ 4440/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5021 | g_total_loss: 2.1298
Epoch [ 4450/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.2234
Epoch [ 4460/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5002 | g_total_loss: 2.4004
Epoch [ 4470/ 8000] | d_X_loss: 0.5030 | d_Y_loss: 0.5002 | g_total_loss: 2.5317
Epoch [ 4480/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5003 | g_total_loss: 2.8697
Epoch [ 4490/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5003 | g_total_loss: 2.6567
Epoch [ 4500/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5002 | g_total_loss: 2.5113
Saved samples_cyclegan/sample-004500-X-Y.png
Saved samples_cyclegan/sample-004500-Y-X.png
Epoch [ 4510/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5004 | g_total_loss: 2.5918
Epoch [ 4520/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.1663
Epoch [ 4530/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5008 | g_total_loss: 2.3520
Epoch [ 4540/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.4307
Epoch [ 4550/ 8000] | d_X_loss: 0.5020 | d_Y_loss: 0.5011 | g_total_loss: 2.2694
Epoch [ 4560/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5003 | g_total_loss: 2.4692
Epoch [ 4570/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5006 | g_total_loss: 2.3614
Epoch [ 4580/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5002 | g_total_loss: 2.3857
Epoch [ 4590/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.2587
Epoch [ 4600/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.3020
Saved samples_cyclegan/sample-004600-X-Y.png
Saved samples_cyclegan/sample-004600-Y-X.png
Epoch [ 4610/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5003 | g_total_loss: 2.2691
Epoch [ 4620/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5010 | g_total_loss: 2.3462
Epoch [ 4630/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5001 | g_total_loss: 2.2264
Epoch [ 4640/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.2729
Epoch [ 4650/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.5257
Epoch [ 4660/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.2325
Epoch [ 4670/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5003 | g_total_loss: 2.3180
Epoch [ 4680/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5011 | g_total_loss: 2.4177
Epoch [ 4690/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.0730
Epoch [ 4700/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5002 | g_total_loss: 2.5774
Saved samples_cyclegan/sample-004700-X-Y.png
Saved samples_cyclegan/sample-004700-Y-X.png
Epoch [ 4710/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5005 | g_total_loss: 2.3575
Epoch [ 4720/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5001 | g_total_loss: 2.3054
Epoch [ 4730/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5003 | g_total_loss: 2.2930
Epoch [ 4740/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.3368
Epoch [ 4750/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5005 | g_total_loss: 2.5333
Epoch [ 4760/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5008 | g_total_loss: 2.3213
Epoch [ 4770/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5005 | g_total_loss: 2.4846
Epoch [ 4780/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.4348
Epoch [ 4790/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5003 | g_total_loss: 2.4659
Epoch [ 4800/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5007 | g_total_loss: 2.4323
Saved samples_cyclegan/sample-004800-X-Y.png
Saved samples_cyclegan/sample-004800-Y-X.png
Epoch [ 4810/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.4239
Epoch [ 4820/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5004 | g_total_loss: 2.2031
Epoch [ 4830/ 8000] | d_X_loss: 0.5048 | d_Y_loss: 0.5001 | g_total_loss: 2.1757
Epoch [ 4840/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5002 | g_total_loss: 2.4986
Epoch [ 4850/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.2474
Epoch [ 4860/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5006 | g_total_loss: 2.4093
Epoch [ 4870/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5005 | g_total_loss: 2.4142
Epoch [ 4880/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5009 | g_total_loss: 2.4712
Epoch [ 4890/ 8000] | d_X_loss: 0.5018 | d_Y_loss: 0.5002 | g_total_loss: 2.4088
Epoch [ 4900/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.4503
Saved samples_cyclegan/sample-004900-X-Y.png
Saved samples_cyclegan/sample-004900-Y-X.png
Epoch [ 4910/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5003 | g_total_loss: 2.3379
Epoch [ 4920/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5006 | g_total_loss: 2.5302
Epoch [ 4930/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5001 | g_total_loss: 2.4928
Epoch [ 4940/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5005 | g_total_loss: 2.6647
Epoch [ 4950/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5004 | g_total_loss: 2.3903
Epoch [ 4960/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5002 | g_total_loss: 2.1251
Epoch [ 4970/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.3693
Epoch [ 4980/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5003 | g_total_loss: 2.2425
Epoch [ 4990/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.2598
Epoch [ 5000/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.2872
Saved samples_cyclegan/sample-005000-X-Y.png
Saved samples_cyclegan/sample-005000-Y-X.png
Epoch [ 5010/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5001 | g_total_loss: 2.3963
Epoch [ 5020/ 8000] | d_X_loss: 0.5025 | d_Y_loss: 0.5004 | g_total_loss: 2.2514
Epoch [ 5030/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5007 | g_total_loss: 2.6300
Epoch [ 5040/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5002 | g_total_loss: 2.5543
Epoch [ 5050/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.3072
Epoch [ 5060/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.3803
Epoch [ 5070/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5001 | g_total_loss: 2.2605
Epoch [ 5080/ 8000] | d_X_loss: 0.5029 | d_Y_loss: 0.5006 | g_total_loss: 2.2178
Epoch [ 5090/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5006 | g_total_loss: 2.4168
Epoch [ 5100/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.1804
Saved samples_cyclegan/sample-005100-X-Y.png
Saved samples_cyclegan/sample-005100-Y-X.png
Epoch [ 5110/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5008 | g_total_loss: 2.3021
Epoch [ 5120/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5001 | g_total_loss: 2.0757
Epoch [ 5130/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5005 | g_total_loss: 2.2564
Epoch [ 5140/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.3273
Epoch [ 5150/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5008 | g_total_loss: 2.2887
Epoch [ 5160/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5026 | g_total_loss: 2.2233
Epoch [ 5170/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5004 | g_total_loss: 2.0929
Epoch [ 5180/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.1443
Epoch [ 5190/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5003 | g_total_loss: 2.2092
Epoch [ 5200/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5001 | g_total_loss: 2.2121
Saved samples_cyclegan/sample-005200-X-Y.png
Saved samples_cyclegan/sample-005200-Y-X.png
Epoch [ 5210/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.0719
Epoch [ 5220/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5001 | g_total_loss: 2.1453
Epoch [ 5230/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5006 | g_total_loss: 2.2262
Epoch [ 5240/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5023 | g_total_loss: 2.3790
Epoch [ 5250/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5006 | g_total_loss: 2.2996
Epoch [ 5260/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5035 | g_total_loss: 2.1654
Epoch [ 5270/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5018 | g_total_loss: 1.8864
Epoch [ 5280/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.2072
Epoch [ 5290/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5012 | g_total_loss: 2.5002
Epoch [ 5300/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5010 | g_total_loss: 2.2334
Saved samples_cyclegan/sample-005300-X-Y.png
Saved samples_cyclegan/sample-005300-Y-X.png
Epoch [ 5310/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5011 | g_total_loss: 2.3349
Epoch [ 5320/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.1981
Epoch [ 5330/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5008 | g_total_loss: 2.2684
Epoch [ 5340/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.4844
Epoch [ 5350/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5007 | g_total_loss: 2.2630
Epoch [ 5360/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5007 | g_total_loss: 2.2606
Epoch [ 5370/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5006 | g_total_loss: 2.4473
Epoch [ 5380/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5014 | g_total_loss: 2.2838
Epoch [ 5390/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5036 | g_total_loss: 2.3680
Epoch [ 5400/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5003 | g_total_loss: 2.4698
Saved samples_cyclegan/sample-005400-X-Y.png
Saved samples_cyclegan/sample-005400-Y-X.png
Epoch [ 5410/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5052 | g_total_loss: 2.0985
Epoch [ 5420/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5028 | g_total_loss: 2.4131
Epoch [ 5430/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5018 | g_total_loss: 2.4170
Epoch [ 5440/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5005 | g_total_loss: 2.3840
Epoch [ 5450/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.3342
Epoch [ 5460/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5004 | g_total_loss: 2.2145
Epoch [ 5470/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5012 | g_total_loss: 2.1247
Epoch [ 5480/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.3657
Epoch [ 5490/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5026 | g_total_loss: 2.0712
Epoch [ 5500/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5007 | g_total_loss: 2.4824
Saved samples_cyclegan/sample-005500-X-Y.png
Saved samples_cyclegan/sample-005500-Y-X.png
Epoch [ 5510/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5004 | g_total_loss: 2.2622
Epoch [ 5520/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.2551
Epoch [ 5530/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.5291
Epoch [ 5540/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5007 | g_total_loss: 2.4165
Epoch [ 5550/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5001 | g_total_loss: 2.3189
Epoch [ 5560/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5002 | g_total_loss: 2.4554
Epoch [ 5570/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5001 | g_total_loss: 2.2292
Epoch [ 5580/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.4180
Epoch [ 5590/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5002 | g_total_loss: 2.2030
Epoch [ 5600/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5007 | g_total_loss: 2.0961
Saved samples_cyclegan/sample-005600-X-Y.png
Saved samples_cyclegan/sample-005600-Y-X.png
Epoch [ 5610/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5010 | g_total_loss: 2.1862
Epoch [ 5620/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5004 | g_total_loss: 2.2588
Epoch [ 5630/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5003 | g_total_loss: 2.2083
Epoch [ 5640/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.2075
Epoch [ 5650/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5012 | g_total_loss: 2.2005
Epoch [ 5660/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.3939
Epoch [ 5670/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.3880
Epoch [ 5680/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5002 | g_total_loss: 2.2595
Epoch [ 5690/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5005 | g_total_loss: 2.3012
Epoch [ 5700/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5009 | g_total_loss: 2.0542
Saved samples_cyclegan/sample-005700-X-Y.png
Saved samples_cyclegan/sample-005700-Y-X.png
Epoch [ 5710/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5010 | g_total_loss: 2.3082
Epoch [ 5720/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5025 | g_total_loss: 2.3299
Epoch [ 5730/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.4481
Epoch [ 5740/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5005 | g_total_loss: 2.1805
Epoch [ 5750/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5010 | g_total_loss: 2.3096
Epoch [ 5760/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5012 | g_total_loss: 2.1218
Epoch [ 5770/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.2695
Epoch [ 5780/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5004 | g_total_loss: 2.3774
Epoch [ 5790/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.3741
Epoch [ 5800/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.1436
Saved samples_cyclegan/sample-005800-X-Y.png
Saved samples_cyclegan/sample-005800-Y-X.png
Epoch [ 5810/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5008 | g_total_loss: 2.0727
Epoch [ 5820/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.3158
Epoch [ 5830/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5005 | g_total_loss: 2.3721
Epoch [ 5840/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5003 | g_total_loss: 2.4103
Epoch [ 5850/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5020 | g_total_loss: 2.3651
Epoch [ 5860/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5011 | g_total_loss: 2.1168
Epoch [ 5870/ 8000] | d_X_loss: 0.5047 | d_Y_loss: 0.5013 | g_total_loss: 1.9582
Epoch [ 5880/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5002 | g_total_loss: 2.1661
Epoch [ 5890/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5011 | g_total_loss: 2.1295
Epoch [ 5900/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5073 | g_total_loss: 2.0039
Saved samples_cyclegan/sample-005900-X-Y.png
Saved samples_cyclegan/sample-005900-Y-X.png
Epoch [ 5910/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.3374
Epoch [ 5920/ 8000] | d_X_loss: 0.5017 | d_Y_loss: 0.5023 | g_total_loss: 2.1411
Epoch [ 5930/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5030 | g_total_loss: 2.2412
Epoch [ 5940/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5006 | g_total_loss: 2.2929
Epoch [ 5950/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5022 | g_total_loss: 2.2055
Epoch [ 5960/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.2992
Epoch [ 5970/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.3856
Epoch [ 5980/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5003 | g_total_loss: 2.2712
Epoch [ 5990/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5007 | g_total_loss: 2.4329
Epoch [ 6000/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5005 | g_total_loss: 2.4016
Saved samples_cyclegan/sample-006000-X-Y.png
Saved samples_cyclegan/sample-006000-Y-X.png
Epoch [ 6010/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5004 | g_total_loss: 2.2457
Epoch [ 6020/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5001 | g_total_loss: 2.1664
Epoch [ 6030/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5013 | g_total_loss: 2.1819
Epoch [ 6040/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5064 | g_total_loss: 2.3099
Epoch [ 6050/ 8000] | d_X_loss: 0.5047 | d_Y_loss: 0.5002 | g_total_loss: 2.3812
Epoch [ 6060/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5017 | g_total_loss: 2.1792
Epoch [ 6070/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.4350
Epoch [ 6080/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5002 | g_total_loss: 2.4724
Epoch [ 6090/ 8000] | d_X_loss: 0.5022 | d_Y_loss: 0.5004 | g_total_loss: 2.2440
Epoch [ 6100/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.3907
Saved samples_cyclegan/sample-006100-X-Y.png
Saved samples_cyclegan/sample-006100-Y-X.png
Epoch [ 6110/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.2825
Epoch [ 6120/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5004 | g_total_loss: 2.2551
Epoch [ 6130/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5033 | g_total_loss: 2.0279
Epoch [ 6140/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5002 | g_total_loss: 2.2514
Epoch [ 6150/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5010 | g_total_loss: 2.2596
Epoch [ 6160/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5005 | g_total_loss: 3.3780
Epoch [ 6170/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5007 | g_total_loss: 2.1346
Epoch [ 6180/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.1830
Epoch [ 6190/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.2602
Epoch [ 6200/ 8000] | d_X_loss: 0.5027 | d_Y_loss: 0.5012 | g_total_loss: 2.3419
Saved samples_cyclegan/sample-006200-X-Y.png
Saved samples_cyclegan/sample-006200-Y-X.png
Epoch [ 6210/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.3903
Epoch [ 6220/ 8000] | d_X_loss: 0.5021 | d_Y_loss: 0.5010 | g_total_loss: 2.0757
Epoch [ 6230/ 8000] | d_X_loss: 0.5016 | d_Y_loss: 0.5003 | g_total_loss: 2.0752
Epoch [ 6240/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.2795
Epoch [ 6250/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.1121
Epoch [ 6260/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5012 | g_total_loss: 2.2170
Epoch [ 6270/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5005 | g_total_loss: 2.0335
Epoch [ 6280/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5014 | g_total_loss: 2.2163
Epoch [ 6290/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.1958
Epoch [ 6300/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5003 | g_total_loss: 2.3550
Saved samples_cyclegan/sample-006300-X-Y.png
Saved samples_cyclegan/sample-006300-Y-X.png
Epoch [ 6310/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5001 | g_total_loss: 2.2645
Epoch [ 6320/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5008 | g_total_loss: 2.4272
Epoch [ 6330/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.1389
Epoch [ 6340/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.5472
Epoch [ 6350/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.1800
Epoch [ 6360/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.1373
Epoch [ 6370/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.3210
Epoch [ 6380/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.2270
Epoch [ 6390/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.3198
Epoch [ 6400/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5007 | g_total_loss: 2.2863
Saved samples_cyclegan/sample-006400-X-Y.png
Saved samples_cyclegan/sample-006400-Y-X.png
Epoch [ 6410/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5005 | g_total_loss: 2.1441
Epoch [ 6420/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5003 | g_total_loss: 2.2885
Epoch [ 6430/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.1034
Epoch [ 6440/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.0648
Epoch [ 6450/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5001 | g_total_loss: 2.0805
Epoch [ 6460/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.2749
Epoch [ 6470/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.0068
Epoch [ 6480/ 8000] | d_X_loss: 0.5026 | d_Y_loss: 0.5008 | g_total_loss: 2.1117
Epoch [ 6490/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5002 | g_total_loss: 2.0888
Epoch [ 6500/ 8000] | d_X_loss: 0.5031 | d_Y_loss: 0.5001 | g_total_loss: 2.2397
Saved samples_cyclegan/sample-006500-X-Y.png
Saved samples_cyclegan/sample-006500-Y-X.png
Epoch [ 6510/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.2325
Epoch [ 6520/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.1119
Epoch [ 6530/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5005 | g_total_loss: 2.2841
Epoch [ 6540/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.2110
Epoch [ 6550/ 8000] | d_X_loss: 0.5023 | d_Y_loss: 0.5001 | g_total_loss: 2.4170
Epoch [ 6560/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5006 | g_total_loss: 2.5040
Epoch [ 6570/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5003 | g_total_loss: 2.3331
Epoch [ 6580/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.3269
Epoch [ 6590/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.1403
Epoch [ 6600/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2845
Saved samples_cyclegan/sample-006600-X-Y.png
Saved samples_cyclegan/sample-006600-Y-X.png
Epoch [ 6610/ 8000] | d_X_loss: 0.5012 | d_Y_loss: 0.5009 | g_total_loss: 2.2391
Epoch [ 6620/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5001 | g_total_loss: 2.1713
Epoch [ 6630/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.3240
Epoch [ 6640/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.1119
Epoch [ 6650/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5003 | g_total_loss: 2.2692
Epoch [ 6660/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.0266
Epoch [ 6670/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.1556
Epoch [ 6680/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.2408
Epoch [ 6690/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.2186
Epoch [ 6700/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5004 | g_total_loss: 2.2898
Saved samples_cyclegan/sample-006700-X-Y.png
Saved samples_cyclegan/sample-006700-Y-X.png
Epoch [ 6710/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5250 | g_total_loss: 2.9167
Epoch [ 6720/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5058 | g_total_loss: 2.3010
Epoch [ 6730/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5096 | g_total_loss: 2.0669
Epoch [ 6740/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5006 | g_total_loss: 2.1904
Epoch [ 6750/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.0929
Epoch [ 6760/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.2001
Epoch [ 6770/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5008 | g_total_loss: 2.8223
Epoch [ 6780/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.1906
Epoch [ 6790/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2077
Epoch [ 6800/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5003 | g_total_loss: 2.3051
Saved samples_cyclegan/sample-006800-X-Y.png
Saved samples_cyclegan/sample-006800-Y-X.png
Epoch [ 6810/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.1247
Epoch [ 6820/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 1.9894
Epoch [ 6830/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.3072
Epoch [ 6840/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.1009
Epoch [ 6850/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5005 | g_total_loss: 2.6672
Epoch [ 6860/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.3674
Epoch [ 6870/ 8000] | d_X_loss: 0.5024 | d_Y_loss: 0.5001 | g_total_loss: 2.3346
Epoch [ 6880/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.0665
Epoch [ 6890/ 8000] | d_X_loss: 0.5014 | d_Y_loss: 0.5003 | g_total_loss: 2.3459
Epoch [ 6900/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.1754
Saved samples_cyclegan/sample-006900-X-Y.png
Saved samples_cyclegan/sample-006900-Y-X.png
Epoch [ 6910/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.1439
Epoch [ 6920/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.1368
Epoch [ 6930/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.2207
Epoch [ 6940/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.1643
Epoch [ 6950/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5005 | g_total_loss: 2.0543
Epoch [ 6960/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5006 | g_total_loss: 2.0967
Epoch [ 6970/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5024 | g_total_loss: 2.3650
Epoch [ 6980/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5003 | g_total_loss: 2.1224
Epoch [ 6990/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5016 | g_total_loss: 1.9738
Epoch [ 7000/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.2094
Saved samples_cyclegan/sample-007000-X-Y.png
Saved samples_cyclegan/sample-007000-Y-X.png
Epoch [ 7010/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.1771
Epoch [ 7020/ 8000] | d_X_loss: 0.5011 | d_Y_loss: 0.5006 | g_total_loss: 2.5270
Epoch [ 7030/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5008 | g_total_loss: 2.0752
Epoch [ 7040/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5005 | g_total_loss: 2.2317
Epoch [ 7050/ 8000] | d_X_loss: 0.5033 | d_Y_loss: 0.5001 | g_total_loss: 2.2422
Epoch [ 7060/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5002 | g_total_loss: 2.2143
Epoch [ 7070/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5001 | g_total_loss: 2.1098
Epoch [ 7080/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5004 | g_total_loss: 2.1136
Epoch [ 7090/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5005 | g_total_loss: 2.2766
Epoch [ 7100/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.2880
Saved samples_cyclegan/sample-007100-X-Y.png
Saved samples_cyclegan/sample-007100-Y-X.png
Epoch [ 7110/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.0376
Epoch [ 7120/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5002 | g_total_loss: 2.0821
Epoch [ 7130/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.1048
Epoch [ 7140/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.0734
Epoch [ 7150/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.1001
Epoch [ 7160/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5015 | g_total_loss: 2.1485
Epoch [ 7170/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5007 | g_total_loss: 2.2102
Epoch [ 7180/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5018 | g_total_loss: 2.2030
Epoch [ 7190/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5003 | g_total_loss: 2.2393
Epoch [ 7200/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5004 | g_total_loss: 2.1980
Saved samples_cyclegan/sample-007200-X-Y.png
Saved samples_cyclegan/sample-007200-Y-X.png
Epoch [ 7210/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.1142
Epoch [ 7220/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.2292
Epoch [ 7230/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5003 | g_total_loss: 2.0172
Epoch [ 7240/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.2711
Epoch [ 7250/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5001 | g_total_loss: 2.2381
Epoch [ 7260/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5011 | g_total_loss: 2.2152
Epoch [ 7270/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.1251
Epoch [ 7280/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5003 | g_total_loss: 2.0095
Epoch [ 7290/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.1508
Epoch [ 7300/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5001 | g_total_loss: 2.2162
Saved samples_cyclegan/sample-007300-X-Y.png
Saved samples_cyclegan/sample-007300-Y-X.png
Epoch [ 7310/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.1375
Epoch [ 7320/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.2822
Epoch [ 7330/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.0474
Epoch [ 7340/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5002 | g_total_loss: 2.3213
Epoch [ 7350/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.3445
Epoch [ 7360/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.2651
Epoch [ 7370/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.1812
Epoch [ 7380/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.6204
Epoch [ 7390/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5002 | g_total_loss: 2.2254
Epoch [ 7400/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5008 | g_total_loss: 2.0682
Saved samples_cyclegan/sample-007400-X-Y.png
Saved samples_cyclegan/sample-007400-Y-X.png
Epoch [ 7410/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5007 | g_total_loss: 2.0910
Epoch [ 7420/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5004 | g_total_loss: 2.2454
Epoch [ 7430/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5001 | g_total_loss: 2.1363
Epoch [ 7440/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.3343
Epoch [ 7450/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5004 | g_total_loss: 2.1957
Epoch [ 7460/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5003 | g_total_loss: 1.9026
Epoch [ 7470/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2783
Epoch [ 7480/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.1897
Epoch [ 7490/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5004 | g_total_loss: 2.1395
Epoch [ 7500/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5004 | g_total_loss: 2.1895
Saved samples_cyclegan/sample-007500-X-Y.png
Saved samples_cyclegan/sample-007500-Y-X.png
Epoch [ 7510/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5003 | g_total_loss: 2.2386
Epoch [ 7520/ 8000] | d_X_loss: 0.5006 | d_Y_loss: 0.5002 | g_total_loss: 2.1926
Epoch [ 7530/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.2030
Epoch [ 7540/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5006 | g_total_loss: 2.1921
Epoch [ 7550/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5004 | g_total_loss: 2.1776
Epoch [ 7560/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.2082
Epoch [ 7570/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5053 | g_total_loss: 2.2057
Epoch [ 7580/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.0335
Epoch [ 7590/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5003 | g_total_loss: 2.1306
Epoch [ 7600/ 8000] | d_X_loss: 0.5028 | d_Y_loss: 0.5001 | g_total_loss: 2.2258
Saved samples_cyclegan/sample-007600-X-Y.png
Saved samples_cyclegan/sample-007600-Y-X.png
Epoch [ 7610/ 8000] | d_X_loss: 0.5019 | d_Y_loss: 0.5001 | g_total_loss: 2.0810
Epoch [ 7620/ 8000] | d_X_loss: 0.5035 | d_Y_loss: 0.5001 | g_total_loss: 2.0752
Epoch [ 7630/ 8000] | d_X_loss: 0.5010 | d_Y_loss: 0.5001 | g_total_loss: 2.3367
Epoch [ 7640/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5003 | g_total_loss: 2.0433
Epoch [ 7650/ 8000] | d_X_loss: 0.5009 | d_Y_loss: 0.5002 | g_total_loss: 2.1953
Epoch [ 7660/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.1601
Epoch [ 7670/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 2.2648
Epoch [ 7680/ 8000] | d_X_loss: 0.5008 | d_Y_loss: 0.5001 | g_total_loss: 2.2929
Epoch [ 7690/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5002 | g_total_loss: 2.2276
Epoch [ 7700/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5003 | g_total_loss: 2.0370
Saved samples_cyclegan/sample-007700-X-Y.png
Saved samples_cyclegan/sample-007700-Y-X.png
Epoch [ 7710/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.2401
Epoch [ 7720/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5002 | g_total_loss: 2.2862
Epoch [ 7730/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.2382
Epoch [ 7740/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.2435
Epoch [ 7750/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5004 | g_total_loss: 2.4176
Epoch [ 7760/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 1.9444
Epoch [ 7770/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5006 | g_total_loss: 2.1378
Epoch [ 7780/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5005 | g_total_loss: 2.2635
Epoch [ 7790/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5022 | g_total_loss: 2.2908
Epoch [ 7800/ 8000] | d_X_loss: 0.5015 | d_Y_loss: 0.5003 | g_total_loss: 1.9777
Saved samples_cyclegan/sample-007800-X-Y.png
Saved samples_cyclegan/sample-007800-Y-X.png
Epoch [ 7810/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5001 | g_total_loss: 2.3951
Epoch [ 7820/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5002 | g_total_loss: 2.1154
Epoch [ 7830/ 8000] | d_X_loss: 0.5013 | d_Y_loss: 0.5002 | g_total_loss: 2.2915
Epoch [ 7840/ 8000] | d_X_loss: 0.5005 | d_Y_loss: 0.5001 | g_total_loss: 2.0752
Epoch [ 7850/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5001 | g_total_loss: 1.9870
Epoch [ 7860/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5010 | g_total_loss: 2.3668
Epoch [ 7870/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5175 | g_total_loss: 2.1717
Epoch [ 7880/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5203 | g_total_loss: 2.1693
Epoch [ 7890/ 8000] | d_X_loss: 0.5001 | d_Y_loss: 0.5034 | g_total_loss: 2.3071
Epoch [ 7900/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5022 | g_total_loss: 2.2257
Saved samples_cyclegan/sample-007900-X-Y.png
Saved samples_cyclegan/sample-007900-Y-X.png
Epoch [ 7910/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5007 | g_total_loss: 2.1622
Epoch [ 7920/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5004 | g_total_loss: 2.0560
Epoch [ 7930/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.6481 | g_total_loss: 2.3107
Epoch [ 7940/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5007 | g_total_loss: 2.2357
Epoch [ 7950/ 8000] | d_X_loss: 0.5032 | d_Y_loss: 0.5010 | g_total_loss: 2.2840
Epoch [ 7960/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5008 | g_total_loss: 2.3980
Epoch [ 7970/ 8000] | d_X_loss: 0.5004 | d_Y_loss: 0.5007 | g_total_loss: 2.1268
Epoch [ 7980/ 8000] | d_X_loss: 0.5002 | d_Y_loss: 0.5003 | g_total_loss: 2.0564
Epoch [ 7990/ 8000] | d_X_loss: 0.5003 | d_Y_loss: 0.5034 | g_total_loss: 3.0309
Epoch [ 8000/ 8000] | d_X_loss: 0.5007 | d_Y_loss: 0.5006 | g_total_loss: 2.4725
Saved samples_cyclegan/sample-008000-X-Y.png
Saved samples_cyclegan/sample-008000-Y-X.png

Tips on Training and Loss Patterns

A lot of experimentation goes into finding the best hyperparameters such that the generators and discriminators don't overpower each other. It's often a good starting point to look at existing papers to find what has worked in previous experiments, I'd recommend this DCGAN paper in addition to the original CycleGAN paper to see what worked for them. Then, you can try your own experiments based off of a good foundation.

Discriminator Losses

When you display the generator and discriminator losses you should see that there is always some discriminator loss; recall that we are trying to design a model that can generate good "fake" images. So, the ideal discriminator will not be able to tell the difference between real and fake images and, as such, will always have some loss. You should also see that $D_X$ and $D_Y$ are roughly at the same loss levels; if they are not, this indicates that your training is favoring one type of discriminator over the other and you may need to look at biases in your models or data.

Generator Loss

The generator's loss should start significantly higher than the discriminator losses because it is accounting for the loss of both generators and weighted reconstruction errors. You should see this loss decrease a lot at the start of training because initial, generated images are often far-off from being good fakes. After some time it may level off; this is normal since the generator and discriminator are both improving as they train. If you see that the loss is jumping around a lot, over time, you may want to try decreasing your learning rates or changing your cycle consistency loss to be a little more/less weighted.

In [24]:
fig, ax = plt.subplots(figsize=(12,8))
losses = np.array(losses)
plt.plot(losses.T[0], label='Discriminator, X', alpha=0.5)
plt.plot(losses.T[1], label='Discriminator, Y', alpha=0.5)
plt.plot(losses.T[2], label='Generators', alpha=0.5)
plt.title("Training Losses")
plt.legend()
Out[24]:
<matplotlib.legend.Legend at 0x7f25de5e0ac8>

Evaluate the Result!

It is useful to see how well the generated images are after an $x$ amount of epochs. This gives us a way to see whether or not the Generators are creating good fake images. For example, the image below depicts real images in the $Y$ set, and the corresponding generated images during different points in the training process. You can see that the generator starts out creating very noisy, fake images, but begins to converge to better representations as it trains (though, not perfect).

Below is a helper function for displaying generated samples based on the passed in training iteration.

In [25]:
import matplotlib.image as mpimg

# helper visualization code
def view_samples(iteration, sample_dir='samples_cyclegan'):
    
    # samples are named by iteration
    path_XtoY = os.path.join(sample_dir, 'sample-{:06d}-X-Y.png'.format(iteration))
    path_YtoX = os.path.join(sample_dir, 'sample-{:06d}-Y-X.png'.format(iteration))
    
    # read in those samples
    try: 
        x2y = mpimg.imread(path_XtoY)
        y2x = mpimg.imread(path_YtoX)
    except:
        print('Invalid number of iterations.')
    
    fig, (ax1, ax2) = plt.subplots(figsize=(18,20), nrows=2, ncols=1, sharey=True, sharex=True)
    ax1.imshow(x2y)
    ax1.set_title('X to Y')
    ax2.imshow(y2x)
    ax2.set_title('Y to X')
In [26]:
# view samples at iteration 100
view_samples(100, 'samples_cyclegan')
In [27]:
# view samples at iteration 1000
view_samples(1000, 'samples_cyclegan')
In [28]:
# view samples at iteration 1000
view_samples(4000, 'samples_cyclegan')
In [29]:
# view samples at iteration 1000
view_samples(8000, 'samples_cyclegan')

Further Challenges and Directions

  • One shortcoming of this model is that it produces fairly low-resolution images; this is an ongoing area of research; you can read about a higher-resolution formulation that uses a multi-scale generator model, in this paper.
  • Relatedly, we may want to process these as larger (say 256x256) images at first, to take advantage of high-res data.
  • It may help your model to converge faster, if you initialize the weights in your network.
  • This model struggles with matching colors exactly. This is because, if $G_{YtoX}$ and $G_{XtoY}$ may change the tint of an image; the cycle consistency loss may not be affected and can still be small. You could choose to introduce a new, color-based loss term that compares $G_{YtoX}(y)$ and $y$, and $G_{XtoY}(x)$ and $x$, but then this becomes a supervised learning approach.
  • This unsupervised approach also struggles with geometric changes, like changing the apparent size of individual object in an image, so it is best suited for stylistic transformations.
  • For creating different kinds of models or trying out the Pix2Pix Architecture, this Github repository which implements CycleGAN and Pix2Pix in PyTorch is a great resource.

Different datasets for download

You can download a variety of datasets used in the Pix2Pix and CycleGAN papers, by following instructions in the associated Github repository. You'll just need to make sure that the data directories are named and organized correctly to load in that data.

In [ ]: